Using UILabel in SwiftUI
But why 😀 well sometime using SwiftUI in an existing App force you to do so.
So here is a SwiftUI View using Text
struct ContentView: View {
var body: some View {
VStack {
Text("This is a SwiftUI text which is easy to use but you need to understand the SwiftUI layout engine.")
.background(Color.black)
.foregroundColor(Color.white)
}
.frame(width: 200)
}
}
Because Text
has no frame, it gets it width from the parent which is a VStack and you see a nice multiline text constrained
by width of the parent 200 pts.
To use UILabel and produce the similar output this is what we need.
struct SUILabel: UIViewRepresentable {
private(set) var preferredMaxLayoutWidth: CGFloat = 0
func makeUIView(context: UIViewRepresentableContext<SUILabel>) -> UILabel {
let label = UILabel()
label.text = """
This is UILabel, one of the most interesting View class in UIKit.
With autolayout and multiline and it often give you some surprises.
Now using it with SwiftUI = 🤯
"""
label.numberOfLines = 0
label.preferredMaxLayoutWidth = preferredMaxLayoutWidth
label.backgroundColor = UIColor.black
label.textColor = UIColor.white
return label
}
func updateUIView(_ uiView: UILabel, context: UIViewRepresentableContext<SUILabel>) { }
}
Using SUILabel in SwiftUI view
struct ContentView: View {
var body: some View {
VStack {
GeometryReader { geometry in
SUILabel(preferredMaxLayoutWidth: geometry.size.width)
.fixedSize(horizontal: true, vertical: true)
}
}
.frame(width: 200)
}
}
The important things to note are, the use of preferredMaxLayoutWidth onUILabel, GeometryReader to fed it to SUILabel and using fixedSize on SUILabel to force SwiftUIlayout engine to use the original size ( in UIKit words, intrinsic content size)