I’m trying center subview. But it doesn’t seem expected. How can I fix it?
here is my codes
private lazy var uploadButton: UIButton = {
let button = UIButton()
let innerView = UIView(frame: CGRect(x: 0, y: 0, width: 136, height: 63))
innerView.backgroundColor = .cyan
innerView.center = CGPoint(x: button.frame.size.width/2, y: button.frame.size.height/2)
button.addSubview(innerView)
button.layer.cornerRadius = 30
button.backgroundColor = .white
button.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
button.layer.shadowOpacity = 1
button.layer.shadowOffset = CGSize.zero
button.layer.shadowRadius = 6
return button
}()
view.addSubview(uploadButton)
uploadButton.translatesAutoresizingMaskIntoConstraints = false
// ...
uploadButton.bottomAnchor.constraint(equalTo: nextButton.topAnchor, constant: -69),
uploadButton.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 38),
uploadButton.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor, constant: -38),
uploadButton.heightAnchor.constraint(equalToConstant: 171)
// all active
2
Answers
I think your code is failing because
innerView
doesn’t have a superview at the time you set itscenter
property. From the docs:What you want is to set
innerView
‘s position inbutton
. Accordingly, you should addinnerView
as a subview ofbutton
first, and then set itscenter
. So, swapping those two lines should solve your problem.There are different layout systems available in iOS
Now, why this inconsistency arises in your snippet?
Your code snippet above has used both
Auto Layout
andFrame-based Layout
which will barely give you desired layout or offer a consistent way for maintenance.Let’s have a look at one case.
uploadButton
is based onautolayout
.innerView
is based onframe-based
layout.uploadButton
, so when you want to setinnerView
center usingbutton.frame.size
early it won’t work as the width and height are zero that time, and will be calculated later upon constraint activation.uploadButton
hadframe-based
layout only thenbutton.frame.size
related calculations would have made sense.TLDR
Stick with only ONE layout system to maintain consistency and intuitiveness as mixing multiple systems can lead to confusion and maintenance issues.
Code
Here, is a working
auto layout
based view.Result
Offtopic?