Reputation: 509
I'm trying to make a login register UI in Swift for iOS without using storyboard.
With this code in my controller:
loginButton.translatesAutoresizingMaskIntoConstraints = false
loginButton.layer.borderWidth = 1
loginButton.clipsToBounds = true
loginButton.layer.borderColor = UIColor.Palette.boldYellow.cgColor
loginButton.setTitle("Login", for: .normal)
loginButton.setTitleColor(UIColor.Palette.boldYellow, for: .normal)
loginButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 24)
loginButton.heightAnchor.constraint(equalToConstant: 58).isActive = true
NSLayoutConstraint(item: loginButton, attribute: .leading, relatedBy: .equal, toItem: footerView, attribute: .leading, multiplier: 1, constant: 30).isActive = true
NSLayoutConstraint(item: loginButton, attribute: .trailing, relatedBy: .equal, toItem: footerView, attribute: .trailing, multiplier: 1, constant: -30).isActive = true
NSLayoutConstraint(item: loginButton, attribute: .top, relatedBy: .equal, toItem: footerView, attribute: .top, multiplier: 1, constant: 21).isActive = true
registerButton.translatesAutoresizingMaskIntoConstraints = false
registerButton.clipsToBounds = true
registerButton.setTitle("Register", for: .normal)
registerButton.setTitleColor(.white, for: .normal)
registerButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 24)
registerButton.heightAnchor.constraint(equalToConstant: 58).isActive = true
NSLayoutConstraint(item: registerButton, attribute: .leading, relatedBy: .equal, toItem: footerView, attribute: .leading, multiplier: 1, constant: 30).isActive = true
NSLayoutConstraint(item: registerButton, attribute: .trailing, relatedBy: .equal, toItem: footerView, attribute: .trailing, multiplier: 1, constant: -30).isActive = true
NSLayoutConstraint(item: registerButton, attribute: .bottom, relatedBy: .equal, toItem: footerView, attribute: .bottom, multiplier: 1, constant: -21).isActive = true
I can achieve this:
But I'd like to make the "Register" text bolder so I add this line:
registerButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 24)
Just before
registerButton.heightAnchor.constraint(equalToConstant: 58).isActive = true
But then, the whole interface is broken and I got this:
Looks like the changes that I made to the layer of both buttons are not applied.
I do these layer changes in the viewDidLayoutSubviews override of my controller :
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let gradientBackgroundButton = CAGradientLayer()
gradientBackgroundButton.frame = registerButton.bounds
gradientBackgroundButton.startPoint = CGPoint.zero
gradientBackgroundButton.endPoint = CGPoint(x: 1, y: 1)
gradientBackgroundButton.colors = [UIColor.Palette.lightYellow.cgColor, UIColor.Palette.boldYellow.cgColor]
registerButton.layer.insertSublayer(gradientBackgroundButton, at: 0)
registerButton.layer.cornerRadius = registerButton.bounds.height / 2
loginButton.layer.cornerRadius = loginButton.bounds.height / 2
}
My guess is that when I don't specify the font size my view needs to call viewDidLayoutSubviews but not when I specify one. In this case where am I supposed to modify the layer of my buttons?
Upvotes: 2
Views: 114
Reputation: 119262
I think your guess is a good one. viewDidLayoutSubviews
could be called many, many times, and currently each time it's called you're going to be creating and adding a new gradient layer. Add a breakpoint to viewDidLayoutSubviews
and see how often it runs and what the button size values are.
You either need to check for the existence of a gradient layer before inserting and sizing it, or ideally move all of this logic into UIButton subclasses, which can keep their own references to the layers and deal with them when the button itself is resized.
Upvotes: 2