I have a UIStackView in IB and I am removing and adding subviews in viewDidLoad. When removing subviews it crashes.
[self.headerStackView.arrangedSubviews each:^(UIView *subview) {
[self.headerStackView removeArrangedSubview:subview];
[subview removeConstraints:subview.constraints];
[subview removeFromSuperview];
}];
Debugger:
2016-11-29 12:35:18.568137 RocheUnregulated[2211:937474] [LayoutConstraints] View hierarchy unprepared for constraint.
Constraint: <NSLayoutConstraint:0x17429ec80 'UISV-spacing' H:[EntryItemInfoView:0x10fe10840]-(15)-[EntryItemInfoView:0x10fd85e50] (active)>
Container hierarchy:
<UIStackView: 0x10fe14160; frame = (125 12; 183 51); opaque = NO; autoresize = RM+BM; layer = <CATransformLayer: 0x1700351c0>>
| <EntryItemInfoView: 0x10fd85e50; frame = (66 0; 51 51); autoresize = RM+BM; layer = <CALayer: 0x1702308e0>>
| | <UIStackView: 0x10fd86570; frame = (10 10; 31 31); opaque = NO; autoresize = RM+BM; layer = <CATransformLayer: 0x170230b00>>
| | | <UILabel: 0x10fd86730; frame = (0 0; 31 20.5); text = '45'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x170480f00>>
| | | <UILabel: 0x10fd86c50; frame = (0 20.5; 31 10.5); text = 'grams'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x170299410>>
| <EntryItemInfoView: 0x10fd86ed0; frame = (132 0; 51 51); autoresize = RM+BM; layer = <CALayer: 0x170230ac0>>
| | <UIStackView: 0x10fd62a00; frame = (10 10; 31 31); opaque = NO; autoresize = RM+BM; layer = <CATransformLayer: 0x170230b60>>
| | | <UILabel: 0x10fd870d0; frame = (0 0; 31 20.5); text = '10'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x170481d10>>
| | | <UILabel: 0x10fd87350; frame = (0 20.5; 31 10.5); text = 'units'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x170481090>>
View not found in container hierarchy: <EntryItemInfoView: 0x10fe10840; frame = (0 0; 51 51); autoresize = RM+BM; layer = <CALayer: 0x17422ad20>>
That view's superview: NO SUPERVIEW
Managing Subviews To remove an arranged subview that you no longer want around, you need to call removeFromSuperview() on it. The stack view will automatically remove it from the arranged subview list.
A streamlined interface for laying out a collection of views in either a column or a row.
This function seems to fix it for me:
extension UIStackView {
func safelyRemoveArrangedSubviews() {
// Remove all the arranged subviews and save them to an array
let removedSubviews = arrangedSubviews.reduce([]) { (sum, next) -> [UIView] in
self.removeArrangedSubview(next)
return sum + [next]
}
// Deactive all constraints at once
NSLayoutConstraint.deactivate(removedSubviews.flatMap({ $0.constraints }))
// Remove the views from self
removedSubviews.forEach({ $0.removeFromSuperview() })
}
}
[self.headerStackView.arrangedSubviews each:^(UIView *subview) {
[self.headerStackView removeArrangedSubview:subview]; // <-- Removes Constraints as well
[subview removeConstraints:subview.constraints];// <--- Constraints will be invalid or non existing
[subview removeFromSuperview];
}];
Try this:
while let first = stackView.arrangedSubviews.first {
stackView.removeArrangedSubview(first)
first.removeFromSuperview()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With