I've a stack view with label, image view and button inside it. This stack view is configured for vertical axis with distribution and alignment set to fill. The label is not aligning to centre of the view as the button does. Why is this weird behaviour seen and how to fix this?
class ViewController: UIViewController {
let flowerLabel: UILabel = {
let label = UILabel()
label.text = "Flowers"
label.font = UIFont.systemFont(ofSize: 25)
label.numberOfLines = 0
return label
}()
var flowerImageView: UIImageView! = {
let flowerImageView = UIImageView(image: UIImage(named: "flowers"))
flowerImageView.contentMode = .scaleAspectFit
flowerImageView.setContentHuggingPriority(.defaultLow - 1, for: .vertical)
flowerImageView.setContentCompressionResistancePriority(.defaultHigh - 1, for: .vertical)
return flowerImageView
}()
var editButton = UIButton.customButton(title: "Edit", color: .blue, fontSize: 25)
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
lazy var stack :UIStackView = {
let stack = UIStackView(arrangedSubviews: [flowerLabel,flowerImageView,editButton])
stack.translatesAutoresizingMaskIntoConstraints = false
stack.axis = .vertical
stack.spacing = 8
stack.alignment = .fill
stack.distribution = .fill
return stack
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(stack)
view.backgroundColor = .white
NSLayoutConstraint.activate([
stack.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8),
stack.bottomAnchor.constraint(equalTo: view.bottomAnchor),
stack.leadingAnchor.constraint(equalTo: view.leadingAnchor),
stack.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
}
}
private extension UIButton {
static func customButton(title: String, color: UIColor,
fontSize: CGFloat) -> UIButton {
let button = UIButton(type: .custom)
button.setTitle(title, for: .normal)
button.setTitleColor(color, for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize:
fontSize)
return button
}
}

You have set
alignmentof the stack view to.fill. This means that the arranged views will fill the entire width of the stack view.When a button is "stretched" to fit the width, its text is centre-aligned. This is because buttons place their
titleLabels in the centre of the button by default.When a
UILabelis stretched to fit the width however, where the text will appear in the label depends on the label'stextAlignment. By default, this is.natural, which in a LTR language, means.left.So you should do:
Alternatively, set the stack view's alignment to
.centerso the label doesn't get stretched.