来自UIStackView类参考
在removeArratedSubview:中
若要在调用堆栈的removeAngedSubview:方法后防止视图出现在屏幕上,请通过调用视图的removeFromSuperview方法从子视图数组中显式删除该视图。
在排列子视图中:
每当调用排列视图的removeFromSuperview方法时,堆栈视图都会从其排列子视图数组中删除该视图
从这些中,似乎只调用removeFromSuperview就足以删除子视图,我一直在这样使用它,没有遇到任何问题。我还通过记录调用removeFromSuperview时arrangedSubviews数组的计数来确认该行为。
然而,这里有很多关于S/O的教程和评论,说两者都可以。这是有原因的吗?还是人们只是因为文件上这么说才这么做?
不,只需调用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)
在iOS 12.0中,您需要使用
stackView.arrangedSubviews[index].removeFromSuperview()
如果使用removeArrangedSubview
,则会出现一个错误,其中指定索引处的视图已删除,但我要清除的视图显示在CGPoint(x: 0, y: 0)
处。
希望这能帮助到别人。
Hacking With Swift提供了一个很好的例子和解释,在本例中使用了Web视图。
原因是您可以从堆栈视图的排列子视图列表中删除某些内容,然后稍后重新添加,而不必每次都重新创建它——它是隐藏的,而不是销毁的。我们不希望内存泄漏,所以我们希望完全删除已删除的网络视图。如果你发现你的内存使用量激增,你可能忘记了这一步!
https://www.hackingwithswift.com/read/31/4/removing-views-from-a-uistackview-with-removearrangedsubview
从stackview中删除arrangedSubview是
// To remove it from the view hierarchy
subView.removeFromSuperview()
您是对的,只要调用removeFromSuperview
就足以完全删除视图。
我怀疑人们把两者都放在一起的原因是他们遇到了removeArrangedSubview
文档,该文档似乎说两者都是需要的。(事实上,如果你调用removeArrangedSubview
并希望视图真的消失,它们就是。)
arrangedSubviews
中的附加文档没有被很多人看到,所以他们没有意识到removeArrangedSubview
在这种情况下是可选的。
否,删除特定视图。
func removeArrangedSubview(_ view: UIView)
删除所有子视图
stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
要删除,请使用此扩展。不知道是否有必要取消限制。但也许这会有所帮助。
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()
}
}
}
}
我建议获得排列好的子视图,然后像下面的代码一样删除它。
for view in self.stackView.arrangedSubviews{
self.stackView.removeArrangedSubview(view)
view.removeFromSuperview()
}
简单答案:NO!(正如之前许多其他人所说)
更长的答案:
// to remove "view" from the stack entirely
// calls removeArrangedSubview()
view.removeFromSuperview()
// to add "view" to the stack
// calls addSubview()
stackView.addArrangeSubview(view)
请查看苹果公司文档中关于此问题的明确段落(Maintain consistency between the arranged views and subview
):https://developer.apple.com/documentation/uikit/uistackview#1653129
这里是重要的部分:
堆栈视图确保其arrangedSubviews属性始终是其subviews属性的子集。特别是,堆栈视图强制执行以下规则:当堆栈视图将一个视图添加到其arrangedSubviews数组中时,如果该视图还没有添加,它也会将该视图添加为子视图。从堆栈视图中删除子视图时,堆栈视图也会将其从arrangedSubviews数组中删除。从arrangedSubviews数组中删除视图不会将其作为子视图删除。堆栈视图不再管理视图的大小和位置,但视图仍然是视图层次结构的一部分,如果可见,则会在屏幕上渲染。