I have the following code
func setupUI() {
self.view.backgroundColor = .white
let titleLbl = UILabel()
titleLbl.text = book.title
titleLbl.textColor = .black
titleLbl.textAlignment = .center
titleLbl.numberOfLines = 0
titleLbl.lineBreakMode = .byWordWrapping
titleLbl.font = UIFont(name: "Inter-Regular", size: 16);
view.addSubview(titleLbl)
// Using Auto Layout
titleLbl.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
titleLbl.centerXAnchor.constraint(equalTo: view.centerXAnchor),
titleLbl.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
titleLbl.heightAnchor.constraint(equalToConstant: 20)
])
innerView = UIView()
innerView.backgroundColor = UIColor(red: 0.92, green: 0.96, blue: 0.99, alpha: 1.00)
innerView.layer.cornerRadius = 12
innerView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(innerView)
NSLayoutConstraint.activate([
innerView.topAnchor.constraint(equalTo: titleLbl.bottomAnchor, constant: 40),
innerView.heightAnchor.constraint(equalToConstant: 300),
innerView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 20),
innerView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -20)
])
let backBtn = UIButton(frame: CGRect(x: self.view.frame.width - 60, y: 55, width: 40, height: 40))
backBtn.setImage(UIImage.init(named: "close-circle"), for: .normal)
backBtn.backgroundColor = UIColor.clear
backBtn.addTarget(self, action: #selector(goback), for: .touchUpInside)
self.view.addSubview(backBtn)
let quote = self.book.quotes![self.currentIndex]
let bodyLbl = UILabel()
bodyLbl.text = quote
bodyLbl.textColor = .black
bodyLbl.textAlignment = .center
bodyLbl.numberOfLines = 0
bodyLbl.lineBreakMode = .byWordWrapping
bodyLbl.font = UIFont(name: "Inter-Regular", size: 16);
innerView.addSubview(bodyLbl)
// Using Auto Layout
bodyLbl.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
bodyLbl.leadingAnchor.constraint(equalTo: innerView.safeAreaLayoutGuide.leadingAnchor, constant: 10),
bodyLbl.topAnchor.constraint(equalTo: innerView.safeAreaLayoutGuide.topAnchor, constant: 20),
bodyLbl.trailingAnchor.constraint(equalTo: innerView.safeAreaLayoutGuide.trailingAnchor, constant: -10)
])
bodyLbl.sizeToFit()
let shareButton = UIButton()
shareButton.setTitle("Share", for: .normal)
shareButton.setTitleColor(.white, for: .normal)
shareButton.backgroundColor = .black
shareButton.addTarget(self, action: #selector(self.share), for: .touchUpInside)
shareButton.layer.cornerRadius = 12
shareButton.clipsToBounds = true
shareButton.isUserInteractionEnabled = true
innerView.addSubview(shareButton)
shareButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
shareButton.centerXAnchor.constraint(equalTo: innerView.centerXAnchor),
shareButton.topAnchor.constraint(equalTo: bodyLbl.bottomAnchor, constant: 40),
shareButton.heightAnchor.constraint(equalToConstant: 30),
shareButton.widthAnchor.constraint(equalToConstant: 150)
])
let count = self.book.quotes!.count
if ((self.currentIndex + 1) > count) {
self.nextBtn.isHidden = true
} else {
self.nextBtn.isHidden = false
}
innerView.setNeedsLayout()
innerView.layoutIfNeeded()
let newSize = innerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
innerView.frame.size = newSize
innerView.sizeToFit()
}
How can I make the innerView fit the size of it's contents? I set the height to 300 but I need it to fit the size of label and share button afterwards. Can someone help? What am I doing wrong? I tried sizeToFit but that doesn't work.
You can remove the constant height constraint, and add
shareButton.bottomAnchor.constraint(equalTo: innerView.safeAreaLayoutGuide.bottomAnchor, constant: -20)
With this constraint, there is now enough information for AutoLayout to determine the height of innerView
, because it knows
bodyLbl
is 20 pt below the top of innerView
bodyLbl
has an intrinsic height based on its contentshareButton
is 40pt below the bottom of bodyLbl
shareButton
has a constant height of 30shareButton
is 20pt above the bottom of innerView
I'd also recommend using UIStackView
for this kind of layout. You don't need to add any constraints to bodyLbl
or shareButton
- just do:
let stackView = UIStackView(arrangedSubviews: [bodyLbl, shareButton])
stackView.axis = .vertical
stackView.alignment = .center
stackView.setCustomSpacing(40, after: bodyLbl)
innerView.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: innerView.safeAreaLayoutGuide.leadingAnchor, constant: 10),
stackView.trailingAnchor.constraint(equalTo: innerView.safeAreaLayoutGuide.trailingAnchor, constant: -10),
stackView.topAnchor.constraint(equalTo: innerView.safeAreaLayoutGuide.topAnchor, constant: 20),
stackView.bottomAnchor.constraint(equalTo: innerView.safeAreaLayoutGuide.bottomAnchor, constant: -20),
shareButton.heightAnchor.constraint(equalToConstant: 30),
shareButton.widthAnchor.constraint(equalToConstant: 150)
])