May 2, 2020

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.


Multiline Text in SwiftUI

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)

Tagged with: