Reputation: 51
I am trying to load a UIStackView from a xib that contains multiple labels into a parent UIStackView. The labels in the child stack get populated with values (or hidden) after the ViewController in the viewDidLoad
method via a model object.
I expect that the parent stackview would recognize the change in intrinsic height of the child stackview, and thus move sibling views down. However, the next view (button) covers the content of the child stack. Why does the parent not recognize this change to a subview's height? I am not seeing any error messages, ambiguous constraints, or conflicts.
Here is how the error renders and how the views appear in the View Hierarchy.
I have tried:
Parent View Controller
class AcceptTermsViewController: RegistrationViewController {
@IBOutlet weak var infoView: StackViewInBorderedView!
@IBOutlet weak var termsView: TermsTextView!
@IBOutlet weak var masterStack: UIStackView!
var registration: Registration?
override func viewDidLoad() {
super.viewDidLoad()
self.configView()
self.setupNavBar()
}
func configView() {
if let reg = registration {
infoView.configView(reg)
}
}
}
Child StackView Code
class StackViewInBorderedView: UIStackView {
// loaded from NIB
private weak var view: UIView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var emailLabel: UILabel!
@IBOutlet weak var locationLabel: UILabel!
@IBOutlet weak var postalLabel: UILabel!
@IBOutlet weak var idLabel: UILabel!
@IBOutlet weak var npiLabel: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
loadViewFromNib()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
loadViewFromNib()
}
fileprivate func loadViewFromNib() {
self.view = Bundle (for: type(of: self)).loadNibNamed(
"StackViewInBorderedView", owner: self, options: nil)! [0] as? UIView
view.frame = bounds
view.autoresizingMask = [.flexibleWidth]
self.addSubview(view)
}
override func layoutSubviews() {
super.layoutSubviews()
self.layer.cornerRadius = 10
let shadowLayer = CAShapeLayer()
shadowLayer.path = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.frame.height / 12).cgPath
shadowLayer.fillColor = UIColor.white.cgColor
shadowLayer.shadowColor = UIColor.gray.cgColor
shadowLayer.shadowOffset = CGSize.zero
shadowLayer.shadowOpacity = 1
shadowLayer.shadowRadius = 3
shadowLayer.masksToBounds = false
self.layer.insertSublayer(shadowLayer, at: 0)
}
func configView(_ reg: Registration) {
configLabels(reg)
isLayoutMarginsRelativeArrangement = true
directionalLayoutMargins = NSDirectionalEdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 0)
}
func configLabels(_ reg: Registration) {
// Name line
if let degree = reg.degree {
nameLabel.text = "\(reg.firstName!) \(reg.lastName!), \(degree)"
} else {
nameLabel.text = "\(reg.firstName!) \(reg.lastName!)"
}
// Title line
if let title = reg.title {
titleLabel.text = title
} else {
titleLabel.isHidden = true
}
// Email line
if let email = reg.email {
emailLabel.text = email
} else {
emailLabel.isHidden = true
}
// Location line
if let city = reg.city, let state = reg.state, let postal = reg.postalCode,
!city.isEmpty, !state.isEmpty, !postal.isEmpty {
postalLabel.text = "\(city), \(state) \(postal)"
} else if let postal = reg.postalCode {
postalLabel.text = postal
}
// NPI line
if let licenseId = reg.licenseId {
switch reg.countryCode {
case "BR":
idLabel.text = "ID"
default:
idLabel.text = "NPI"
}
npiLabel.text = licenseId
} else {
self.idLabel.isHidden = true
self.npiLabel.isHidden = true
}
}
}
Upvotes: 1
Views: 659
Reputation: 51
A colleague of mine found the answer.
When loading the view from the nib, I needed to call self.addArrangedSubview
instead of self.addSubview
which provides the intended behavior.
Upvotes: 1