There are different layout systems available in iOS
- Auto Layout
- Frame-Based Layout
- Stack Views
- SwiftUI
Now, why this inconsistency arises in your snippet?
Your code snippet above has used both Auto Layout
and Frame-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 on autolayout
.
innerView
is based on frame-based
layout.
- Auto layout will dynamically calculate the view size of your
uploadButton
, so when you want to set innerView
center using button.frame.size
early it won't work as the width and height are zero that time, and will be calculated later upon constraint activation.
- If
uploadButton
had frame-based
layout only then button.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.
private lazy var innerView: UIView = {
let innerView = UIView()
innerView.translatesAutoresizingMaskIntoConstraints = false
innerView.backgroundColor = .cyan
return innerView
}()
private lazy var uploadButton: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .white
return button
}()
....
....
// then in viewDidLoad() where you structure view elements
view.addSubview(uploadButton)
uploadButton.addSubview(innerView)
// Try replacing this constraint activation part with any utility extension
// or storyboard or available library with less code
let uploadButtonConstraints = [
uploadButton.leftAnchor.constraint(equalTo: view.leftAnchor),
uploadButton.rightAnchor.constraint(equalTo: view.rightAnchor),
uploadButton.topAnchor.constraint(equalTo: view.topAnchor),
uploadButton.bottomAnchor.constraint(equalTo: view.bottomAnchor)
]
NSLayoutConstraint.activate(uploadButtonConstraints)
let innerViewConstraints = [
innerView.heightAnchor.constraint(equalToConstant: 63), // hardcoding is bad
innerView.widthAnchor.constraint(equalToConstant: 136),
innerView.centerXAnchor.constraint(equalTo: uploadButton.centerXAnchor),
innerView.centerYAnchor.constraint(equalTo: uploadButton.centerYAnchor)
]
NSLayoutConstraint.activate(innerViewConstraints)
....
Result

Offtopic?
When designing an API for developers in a language or platform, it is ideal to provide a single approach to accomplish a task. This simplifies the API and minimizes confusion, for example, as demonstrated by the guiding principles of Go language design.
However, as a language or platform evolves, it goes through various phases of development, such as the transition of iOS app layout from Frame-based to Auto Layout to SwiftUI. To maintain backward compatibility previous APIs are kept available as well, which results in developers being exposed to multiple approaches to achieve the same goal or view, leading to confusion when those approaches get mixed.