ios UIStackView:真的有必要同时调用removeFromSuperView和removeArrangedSubview来删除子视图吗?

r9f1avp5  于 2023-07-01  发布在  iOS
关注(0)|答案(9)|浏览(204)

UIStackView Class Reference
在removeArrangedSubview中:
要防止视图在调用堆栈的removeArrangedSubview后显示在屏幕上,请执行以下操作:方法,则通过调用视图的removeFromSuperview方法,显式地从子视图数组中移除视图。
在arrangedSubview中:
每当调用排列视图的removeFromSuperview方法时,堆栈视图就会从其arrangedSubview数组中删除该视图
从这些例子来看,似乎只调用removeFromSuperview就足以删除一个子视图,我一直这样使用它,没有任何问题。我还通过在调用removeFromSuperview时记录arrangedSubviews数组的计数来确认该行为。
这里有很多关于S/O的教程和评论,但是,说要同时调用两者。有什么原因吗?或者人们只是因为文档这么说就这么做了?

dvtswwa3

dvtswwa31#

不,只要调用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)
ztmd8pv5

ztmd8pv52#

在iOS 12.0中,您需要使用

stackView.arrangedSubviews[index].removeFromSuperview()

如果你使用removeArrangedSubview,会有一个bug,在指定的索引处的视图被删除了,但是我想清除的视图出现在CGPoint(x: 0, y: 0)处。
希望这对某人有帮助。

8cdiaqws

8cdiaqws3#

Hacking With Swift提供了一个很好的例子和解释,在这种情况下使用Web视图。
原因是你可以从堆栈视图的子视图列表中删除一些东西,然后在以后重新添加它,而不必每次都重新创建它--它是隐藏的,而不是销毁的。我们不希望出现内存泄漏,因此我们希望完全删除已删除的Web视图。如果你发现你的内存使用量膨胀,你可能忘记了这一步!
https://www.hackingwithswift.com/read/31/4/removing-views-from-a-uistackview-with-removearrangedsubview

2wnc66cl

2wnc66cl4#

从stackview中移除arrangedSubview是

// To remove it from the view hierarchy
   subView.removeFromSuperview()
gkn4icbw

gkn4icbw5#

您是对的,只需调用removeFromSuperview就足以完全删除视图。
我怀疑人们把这两个都放进去的原因是因为他们遇到了removeArrangedSubview文档,其中似乎说这两个都是需要的。(事实上,如果您调用removeArrangedSubview并希望视图真的消失,它们确实是。
arrangedSubviews中的附加文档没有那么多人看到,所以他们没有意识到removeArrangedSubview在这种情况下是可选的。

wkyowqbh

wkyowqbh6#

否,删除特定视图。

func removeArrangedSubview(_ view: UIView)

删除所有子视图

stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
y53ybaqx

y53ybaqx7#

我使用这个扩展来删除。我真的不知道是否有必要取消限制。但也许会有帮助。

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()
            }
        }
    }
}
pn9klfpd

pn9klfpd8#

我会建议得到安排的子视图,然后删除它像下面的代码。

for view in self.stackView.arrangedSubviews{
      self.stackView.removeArrangedSubview(view)
      view.removeFromSuperview()
}
bn31dyow

bn31dyow9#

答案很简单:*****************

更长的答案:

// to remove "view" from the stack entirely 
// calls removeArrangedSubview()
view.removeFromSuperview()
// to add "view" to the stack
// calls addSubview()
stackView.addArrangeSubview(view)

请查看Apple文档中关于此问题的明确段落(Maintain consistency between the arranged views and subview):https://developer.apple.com/documentation/uikit/uistackview#1653129
以下是重要的部分:
堆栈视图确保其arrangedSubviews属性始终是其subviews属性的子集。具体来说,堆栈视图强制执行以下规则:当堆栈视图将视图添加到其arrangedSubviews数组时,它也将该视图添加为子视图(如果尚未添加)。当从堆栈视图中移除子视图时,堆栈视图也会将其从arrangedSubviews数组中移除。从arrangedSubviews数组中删除视图不会将其作为子视图删除。堆栈视图不再管理视图的大小和位置,但视图仍然是视图层次结构的一部分,如果可见,则在屏幕上呈现。

相关问题