UIView removeFromSuperview 正在调用 didMoveToSuperview

Posted

技术标签:

【中文标题】UIView removeFromSuperview 正在调用 didMoveToSuperview【英文标题】:UIView removeFromSuperview is calling didMoveToSuperview 【发布时间】:2016-11-14 01:34:38 【问题描述】:

我不明白为什么 UIView 的 removeFromSuperview 会调用 didMoveToSuperview

我认为didMoveToSuperview 仅在将视图添加到视图时才被调用。谁能解释一下为什么removeFromSuperview 打电话给didMoveToSuperview

这是我在removeFromSuperview做的事情:

public override func removeFromSuperview() 

    clearDelegates()

    chaosPad?.removeFromSuperview()
    brushSliders?.removeFromSuperview()
    moodSlider?.removeFromSuperview()
    brushShapeMenu?.removeFromSuperview()
    moodMenu?.removeFromSuperview()
    gravityMenu?.removeFromSuperview()
    rotationMenu?.removeFromSuperview()

    menuGroups = []
    centerButtons = []
    scrollMenuItems = []
    menu?.removeFromSuperview()
    menu = nil

    super.removeFromSuperview()


func clearDelegates() 
    chaosPad?.delegate = nil
    viewController = nil

这是显示如何调用didMoveToSuperview 的调用堆栈:

#0  0x0000000110f39708 in specialized _fatalErrorMessage(StaticString, StaticString, StaticString, UInt) -> () ()
#1  0x000000010b9cb960 in TDTOilistMenuPainting.configureFrames() -> () at /FastDev/TDTPhotoLib/Oilist/Classes/TDTOilistMenuPainting.swift:161
#2  0x000000010b9cb83e in TDTOilistMenuPainting.didMoveToSuperview() -> () at /FastDev/TDTPhotoLib/Oilist/Classes/TDTOilistMenuPainting.swift:146
#3  0x000000010b9cb872 in @objc TDTOilistMenuPainting.didMoveToSuperview() -> () ()
#4  0x000000010f5d1db5 in __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke ()
#5  0x000000010dc87c60 in -[NSISEngine withBehaviors:performModifications:] ()
#6  0x000000010f5d19b1 in -[UIView(Hierarchy) _postMovedFromSuperview:] ()
#7  0x000000010f5cf610 in __UIViewWasRemovedFromSuperview ()
#8  0x000000010f5cf107 in -[UIView(Hierarchy) removeFromSuperview] ()
#9  0x000000010b9c9aba in TDTOilistMenuPainting.removeFromSuperview() -> () at /FastDev/TDTPhotoLib/Oilist/Classes/TDTOilistMenuPainting.swift:73
#10 0x000000010ba6d269 in TDTPaintingViewController.(navigationController(UINavigationController, animationControllerForOperation : UINavigationControllerOperation, fromViewController : UIViewController, toViewController : UIViewController) -> UIViewControllerAnimatedTransitioning?).(closure #2) at /FastDev/TDTPhotoLib/Oilist/Classes/TDTPaintingViewController.swift:2706

【问题讨论】:

您的意思是说“我认为didMoveToSuperview 仅在视图添加到视图时才被调用”? 好的,谢谢,我编辑了帖子。 【参考方案1】:

这是正常行为。 didMoveToSuperview 会在视图的父视图更改时调用,即使它更改为 nil。您可以检查该方法中的父视图是否为 nil,以确定它是否已添加到其父视图中或从其父视图中删除,例如:

override func didMoveToSuperview() 
    if let superview = self.superview 
        // the view was added as a subview to superview
    
    else 
        // the view was removed from its superview
    

【讨论】:

感谢您的确认。我很惊讶它被称为。 是的,这是一个奇怪的方法,当然。我觉得 Apple 应该将其命名为 superviewDidChange 或类似的名称。 我完全同意! @TylerTheCompiler 令人惊讶的是, documentation 甚至已经这样描述了它:“告诉视图它的超级视图发生了变化。”

以上是关于UIView removeFromSuperview 正在调用 didMoveToSuperview的主要内容,如果未能解决你的问题,请参考以下文章

如果其他 UIView 带有隐藏选项,如何使下 UIView 固定到 UIScrollView 中的上 UIView?

在 UIView2 上方显示 UIView1,但在 UIView1 上方显示 UIView2 输入方式

统计从多个 UIView 中随机抽出的 UIView 数量,即:从 9 个 UIView 中随机抽出 5 个 UIView,然后执行操作

UIView 类别 - 自定义方法不返回 UIView

IOS将UIVIew中的UIImageView扁平化为单个UIView [重复]

UIView - 啥覆盖将允许更新 UIView 框架