iOS中调用removeFromSuperview()后视图未从父视图移除的问题
CustomView调用
removeFromSuperview()后未被移除的排查方案 结合你提供的代码,我梳理了几个最可能导致这个问题的原因,以及对应的解决办法:
1. 重复创建CustomView导致引用丢失
你的代码每次检测到联网时,都会重新加载Nib创建一个新的CustomView实例并赋值给myView。这就会出现一个隐形问题:
- 第一次联网:创建CustomView A,添加到
self.view,myView指向A - 第二次联网:又创建CustomView B,添加到
self.view,myView现在指向B - 断网时调用
removeFromSuperview(),只会移除B,而A还留在self.view上,看起来像是CustomView没被移除
解决办法:先检查myView是否已存在,存在的话直接复用(显示它),不存在再创建新的;断网移除后清空引用:
func internetStatusChanegd(){ if isOnline { collectionView.isHidden = true if let existingView = myView { // 已有CustomView,直接显示 existingView.isHidden = false } else { // 没有的话再创建并添加 if let viewNib = UIView.loadFromNibNamed("CustomView", bundle: Bundle.main) as? CustomView { myView = viewNib myView!.frame = self.view.bounds self.view.addSubview(myView!) } } } else { // 移除并清空引用,避免残留旧实例 myView?.removeFromSuperview() myView = nil collectionView.isHidden = false } }
2. UI操作不在主线程执行
internetStatusChanegd()如果是在子线程触发的(比如网络状态监听的回调通常默认在子线程),直接调用removeFromSuperview()这类UI操作是不会生效的——UIKit的所有UI操作必须在主线程执行。
解决办法:把所有UI相关的代码包在主线程异步调用里:
func internetStatusChanegd(){ DispatchQueue.main.async { [weak self] in guard let self = self else { return } if self.isOnline { self.collectionView.isHidden = true if let existingView = self.myView { existingView.isHidden = false } else { if let viewNib = UIView.loadFromNibNamed("CustomView", bundle: Bundle.main) as? CustomView { self.myView = viewNib self.myView!.frame = self.view.bounds self.view.addSubview(self.myView!) } } } else { self.myView?.removeFromSuperview() self.myView = nil self.collectionView.isHidden = false } } }
注意加上
[weak self]避免循环引用,防止内存泄漏。
3. 验证父视图是否正确
可以在调用removeFromSuperview()前后打印调试信息,确认myView的父视图是否是你预期的self.view:
func internetStatusChanegd(){ // ... 其他代码 } else { print("移除前myView的父视图: \(myView?.superview)") print("当前self.view的子视图数量: \(self.view.subviews.count)") myView?.removeFromSuperview() myView = nil print("移除后self.view的子视图数量: \(self.view.subviews.count)") collectionView.isHidden = false } }
如果打印发现父视图不是self.view,那就要检查addSubview的代码是不是不小心加到了其他视图上(比如collectionView)。
内容的提问来源于stack exchange,提问作者j.doe
相关产品推荐
相关产品推荐

