'UIStackView : Is it really necessary to call both removeFromSuperView and removeArrangedSubview to remove a subview?
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?
Solution 1:[1]
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:[2]
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:[3]
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:[4]
To remove a arrangedSubview from a stackview is
// To remove it from the view hierarchy
subView.removeFromSuperview()
Solution 5:[5]
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:[6]
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:[7]
No, To remove specific view.
func removeArrangedSubview(_ view: UIView)
To remove all subviews
stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
Solution 8:[8]
I will suggest get arranged subviews then remove it like below code .
for view in self.stackView.arrangedSubviews{
self.stackView.removeArrangedSubview(view)
view.removeFromSuperview()
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Max Desiatov |
| Solution 2 | Changnam Hong |
| Solution 3 | inreflection7 |
| Solution 4 | |
| Solution 5 | Graham Perks |
| Solution 6 | Nike Kov |
| Solution 7 | General Grievance |
| Solution 8 |
