Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing Arranged Subviews from UIStackView Crashes App

Tags:

objective-c

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
like image 769
Jacob Van Brunt Avatar asked Nov 29 '16 17:11

Jacob Van Brunt


People also ask

How do I remove all Subviews from Uistackview?

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.

What is Uistackview?

A streamlined interface for laying out a collection of views in either a column or a row.


2 Answers

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() })
    }
}
like image 144
Max Chuquimia Avatar answered Nov 13 '22 16:11

Max Chuquimia


[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()
}
like image 21
Ken Franklin Avatar answered Nov 13 '22 14:11

Ken Franklin