UIStackView : Is it really necessary to call both removeFromSuperView and removeArrangedSubview to remove a subview?
IosUistackviewIos Problem Overview
From the UIStackView Class Reference
In removeArrangedSubview:
>To prevent the view from appearing on screen after calling the stack’s removeArrangedSubview: method, explicitly remove the view from the subviews array by calling the view’s removeFromSuperview method.
In arrangedSubview: >Whenever an arranged view’s removeFromSuperview method is called, the stack view removes the view from its arrangedSubview array
From these, it seems that calling just removeFromSuperview is enough to remove a subview and I've been using it like that without problems. I also confirmed the behavior by logging the count of the arrangedSubviews array when removeFromSuperview is called.
A lot of tutorials and comments here on S/O however, say to call both. Is there a reason for this? Or do people just do it because the documentation says so?
Ios Solutions
Solution 1 - Ios
No, just call subview.removeFromSuperview()
> /* Removes a subview from the list of arranged subviews without removing it as > a subview of the receiver. > To remove the view as a subview, send it -removeFromSuperview as usual; > the relevant UIStackView will remove it from its arrangedSubviews list > automatically. > */ > open func removeArrangedSubview(_ view: UIView)
Solution 2 - Ios
In iOS 12.0, You need to use
stackView.arrangedSubviews[index].removeFromSuperview()
If you use removeArrangedSubview
, there is a bug where the view at the specified index removed, but the view I want to clear appears at CGPoint(x: 0, y: 0)
.
Hope this help someone.
Solution 3 - Ios
Hacking With Swift provides a pretty good example and explanation, using Web views in this case.
> The reason is that you can remove something from a stack view's arranged subview list then re-add it later, without having to recreate it each time – it was hidden, not destroyed. We don't want a memory leak, so we want to remove deleted web views entirely. If you find your memory usage ballooning, you probably forgot this step!
Solution 4 - Ios
To remove a arrangedSubview from a stackview is
// To remove it from the view hierarchy
subView.removeFromSuperview()
Solution 5 - Ios
You're right, just the call to removeFromSuperview
is sufficient to have the view fully removed.
I suspect the reason for people putting both is because they run across the removeArrangedSubview
documentation which seems to say both are needed. (And indeed, they are, if you call removeArrangedSubview
and want the view really gone.)
The additional doc in arrangedSubviews
is not seen by so many, so they don't realize removeArrangedSubview
is, in this case, optional.
Solution 6 - Ios
For removing i use this extension. Don't really know is it necessary to remove constraints. But maybe it would help.
extension UIStackView {
func removeAllArrangedSubviews() {
let removedSubviews = arrangedSubviews.reduce([]) { (allSubviews, subview) -> [UIView] in
self.removeArrangedSubview(subview)
return allSubviews + [subview]
}
for v in removedSubviews {
if v.superview != nil {
NSLayoutConstraint.deactivate(v.constraints)
v.removeFromSuperview()
}
}
}
}
Solution 7 - Ios
No, To remove specific view.
func removeArrangedSubview(_ view: UIView)
To remove all subviews
stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
Solution 8 - Ios
I will suggest get arranged subviews then remove it like below code .
for view in self.stackView.arrangedSubviews{
self.stackView.removeArrangedSubview(view)
view.removeFromSuperview()
}