Reputation: 519
At the moment I am coding an Event-UIViewController
which has three UITableViews
displaying the participants, the intresteds and the people who can't come. Each one of them is anchored right under a Label.
The hierarchy looks like this:
descriptionLabel
|surePeopleLabel
|surePeopleTV
|maybePeopleLabel
|maybePeopleTV
|nopePeopleLabel
|nopePeopleTV
Now I only want to display the Labels and TableViews which are relevant. For example if there are no interested people, it should not display the associated Elements.
But this leads to a problem: Because the nopePeopleLabel
's constraint is set to the bottomAnchor of the maybePeopleTV
which was never added, the program crashes.
Does anyone know a (smooth) approach to set an anchor to the next existing upper object? I added my code even though It is not necessary..
if let sureUsers = surePeopleTV.users, !sureUsers.isEmpty {
scrollView.addSubview(surePeopleLabel)
scrollView.addSubview(surePeopleTV)
let sureTVHeight: CGFloat = CGFloat(sureUsers.count) * 60
surePeopleLabel.anchor(top: descLabel.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 20, paddingLeft: padding, paddingBottom: 0, paddingRight: padding, width: 0, height: 0)
surePeopleTV.anchor(top: surePeopleLabel.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 5, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: sureTVHeight)
}
if let maybeUsers = maybePeopleTV.users, !maybeUsers.isEmpty {
scrollView.addSubview(maybePeopleLabel)
scrollView.addSubview(maybePeopleTV)
let maybeTVHeight: CGFloat = CGFloat(maybeUsers.count) * 60
maybePeopleLabel.anchor(top: surePeopleTV.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 20, paddingLeft: padding, paddingBottom: 0, paddingRight: padding, width: 0, height: 0)
maybePeopleTV.anchor(top: maybePeopleLabel.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 5, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: maybeTVHeight)
}
if let nopeUsers = nopePeopleTV.users, !nopeUsers.isEmpty {
scrollView.addSubview(nopePeopleLabel)
scrollView.addSubview(nopePeopleTV)
let nopeTVHeight: CGFloat = CGFloat(nopeUsers.count) * 60
nopePeopleLabel.anchor(top: maybePeopleLabel.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 20, paddingLeft: padding, paddingBottom: 0, paddingRight: padding, width: 0, height: 0)
nopePeopleTV.anchor(top: nopePeopleLabel.bottomAnchor, left: view.leftAnchor, bottom: scrollView.bottomAnchor, right: view.rightAnchor, paddingTop: 5, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: nopeTVHeight)
}
Upvotes: 0
Views: 54
Reputation: 535536
You’re overthinking this.
Don’t remove any objects (labels or table views). Instead, just change their heights (and the intervening spacing constraints) to zero. This is actually easiest if each label-table pair is inside a superview that can then be adjusted as needed.
Alternatively, use a stack view. It automatically deals with views as you hide and show them, adjusting the constraints for you.
Upvotes: 1
Reputation: 519
var lowestObjAnchor: NSLayoutYAxisAnchor = descLabel.bottomAnchor
Override this property everytime the lowest anchor changes and you'll be fine. In code this would look like this:
if let sureUsers = surePeopleTV.users, !sureUsers.isEmpty {
scrollView.addSubview(surePeopleLabel)
scrollView.addSubview(surePeopleTV)
let sureTVHeight: CGFloat = CGFloat(sureUsers.count) * 60
surePeopleLabel.anchor(top: lowestObjAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 20, paddingLeft: padding, paddingBottom: 0, paddingRight: padding, width: 0, height: 0)
surePeopleTV.anchor(top: surePeopleLabel.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 5, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: sureTVHeight)
lowestObjAnchor = surePeopleTV.bottomAnchor
}
Upvotes: 1