Warm tip: This article is reproduced from serverfault.com, please click

How can I add padding (and a background) to a UILabel

发布于 2020-12-01 09:21:54

This has been asked before on Stackoverflow but the solutions don't work for me.

I'm building an app in SwiftUI but I need to use MapKit for maps, so I'm creating some views in UIKit (programmatically, no interface builder). My current problem is that I want to make a capsule background with some padding around a UILabel. It needs to accommodate arbitrary text, so I can't hardcode the sizes, but I can't find a way to determine the innate size of the UILabel text at runtime. I've tried UIEdgeInsets without success.

In the attached code, I am showing a SwiftUI version of what I'm trying to achieve, and then the UIKit attempt. I'd like to follow best practices, so please feel free to tell me any better ways of achieving this.

(Screenshot of what the code produces)

import SwiftUI

struct SwiftUICapsuleView: View {
    var body: some View {
        Text("Hello, World!")
            .padding(6)
            .background(Color.gray)
            .cornerRadius(15)
    }
}

struct UIKitCapsuleView: UIViewRepresentable {
    func makeUIView(context: Context) -> UIView {
        let view = UIView(frame: .zero)
        view.translatesAutoresizingMaskIntoConstraints = false

        let label = UILabel(frame: .zero)
        label.numberOfLines = 0
        label.font = UIFont.systemFont(ofSize: 17)
        label.text = "Goodbye, World!"
        label.layer.cornerRadius = 15
        label.layer.backgroundColor = UIColor.gray.cgColor
        label.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(label)
        label.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
        label.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true

        return view
    }

    func updateUIView(_ view: UIView, context: Context) {
    }
}

struct ExperimentView_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            SwiftUICapsuleView()
            UIKitCapsuleView()
        }
    }
}
Questioner
gtrichar
Viewed
0
DonMag 2020-12-02 01:38:41

You probably want to set the background color and rounded corners of the view, not the label.

You also should use a full set of constraints.

Give this a try:

struct UIKitCapsuleView: UIViewRepresentable {
    func makeUIView(context: Context) -> UIView {
        let view = UIView(frame: .zero)
        view.translatesAutoresizingMaskIntoConstraints = false
        
        // set the view's background color
        view.backgroundColor = .cyan

        // set the cornerRadius on the view's layer
        view.layer.cornerRadius = 15
        
        let label = UILabel(frame: .zero)
        label.numberOfLines = 0
        label.font = UIFont.systemFont(ofSize: 17)
        label.text = "Goodbye, World!"
        
        label.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(label)

        // you can adjust padding here
        let padding: CGFloat = 6
        
        // use full constraints
        NSLayoutConstraint.activate([
            label.topAnchor.constraint(equalTo: view.topAnchor, constant: padding),
            label.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
            label.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding),
            label.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -padding),
        ])

        return view
    }
    
    func updateUIView(_ view: UIView, context: Context) {
    }
}