Configure Label and Circular Progress Bar in Init vs layoutSubviews

  Kiến thức lập trình

I’m working on a speed test app which has a custom CircularProgressView that includes a speedLabel and the speedLabel is centered in the progress view.

I have a createCircularPath method to create the progress view’s path and I call it inside of layoutSubviews.

When I configure the speedLabel in the custom view’s init and run the speed test then the speedLabel text and the progressTrack is updating as expected as the test is running. But if I configure the speedLabel in layoutSubviews together with the circular path than neither of them are being updated.

I have tried playing with it by changing the z-scores. I’ve also tried embedding the circular path, progressLayer and trackLayer inside another view then adding the view and label as subviews, but still the progress and speed are not being updated during the speed test when configured inside the layoutSubviews.

Looking for an explanation as to why this is.

Screen captures of working progress (when speedLabel configured in init):
enter image description here
enter image description here

And when when speedLabel configured in layoutSubviews the label and progress just stay static. Below is code when both configured in layoutSubviews

import UIKit

class CircularProgressView: UIView {
    
    var progressLayer = CAShapeLayer()
    var trackLayer = CAShapeLayer()
    var speedLabel = UILabel()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        createCircularPath()
        configureSpeedLabel()
    }
    
    var progressColor = UIColor.white {
        didSet {
            progressLayer.strokeColor = progressColor.cgColor
        }
    }
    
    var trackColor = UIColor.white {
        didSet {
            trackLayer.strokeColor = trackColor.cgColor
        }
    }
    
    var speed = 0 {
        didSet {
            speedLabel.text = String(speed)
        }
    }
    
    fileprivate func configureSpeedLabel() {
        speedLabel.translatesAutoresizingMaskIntoConstraints = false
        speedLabel.text = String(speed)
        speedLabel.font = UIFont(name: "TimesNewRomanPSMT", size: 24)
        speedLabel.textColor = UIColor.black
        speedLabel.isOpaque = true
        self.addSubview(speedLabel)
        NSLayoutConstraint.activate([
            speedLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor),
            speedLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor)
        ])
    }
    fileprivate func createCircularPath() {
        self.backgroundColor = UIColor.clear
        self.layer.cornerRadius = self.frame.width/2
        let path = UIBezierPath(arcCenter: CGPoint(x: frame.width/2, y: frame.height/2), radius: (frame.width - 1.5)/2, startAngle: CGFloat(-0.5 * .pi), endAngle: CGFloat(1.5 * .pi), clockwise: true)
        trackLayer.path = path.cgPath
        trackLayer.fillColor = UIColor.clear.cgColor
        trackLayer.strokeColor = trackColor.cgColor
        trackLayer.opacity = 0.3
        trackLayer.lineWidth = 10.0
        trackLayer.strokeEnd = 1.0
        self.layer.addSublayer(trackLayer)

        progressLayer.path = path.cgPath
        progressLayer.fillColor = UIColor.clear.cgColor
        progressLayer.strokeColor = progressColor.cgColor
        progressLayer.lineWidth = 10.0
        progressLayer.strokeEnd = 0.0
        self.layer.addSublayer(progressLayer)
    }

}

LEAVE A COMMENT