UILabel.text is overlapping on change

125 Views Asked by At

I have a simple UIViewController with UILabel and UIButton:

class MyScreen: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .blue
        let values = ["AAA", "BBB", "CCC", "DDD"]
        var index = 0
        let label = UILabel(frame: .init(x: 100, y: 100, width: 100, height: 50))
        label.textColor = .yellow
        view.addSubview(label)
        let button = UIButton(frame: .init(x: 100, y: 200, width: 100, height: 50))
        button.setTitle("Tap", for: .normal)
        button.addAction(.init(handler: { _ in
            label.text = values[index]
            label.backgroundColor = (index % 2 == 0 ? nil : .red)
            index = (index + 1) % values.count
        }), for: .primaryActionTriggered)
        view.addSubview(button)
    }
}

As you can see I just change label.text and label.backgroundColor on tap. However, the text is overlapping. And label.backgroundColor is always .red. iPhone Simulator

Is it an iOS bug? Or how can I change UILabel.text without overlapping?

3

There are 3 best solutions below

2
Roman Podymov On BEST ANSWER

To fix this issue replace label.backgroundColor = (index % 2 == 0 ? nil : .red) with label.backgroundColor = (index % 2 == 0 ? .clear : .red). You should not use nil for UILabel.backgroundColor.

0
fei On

I think you want to make Label background color clear, so set to .clear or don't set background is well.

UIKit seems to change some value of views when drawing. If the label has no color (no something to fill contents), can set isOpaque = false to try.

0
xfost On

I'm able to reproduce your text overlapping issue and background mismatch while UILabel background color is resetted to nil: label.backgroundColor = (index % 2 == 0 ? nil : .red)

As mentioned in other comments you should set it to .clear or .black instead of nil, it definitely fix the overlapping issue and the background is swapping correctly on my side. Still strange that this issue exists, might that be a kind of fallback of the UILabel that is not expecting a nil. (debugging shows nothing strange tho and there are other issues on Slack talking about strange behaviours with nil as background, UILabel default value should probably be .clear in source code).