调用removeFromSuperview后如何防止子视图释放自我?

Posted

技术标签:

【中文标题】调用removeFromSuperview后如何防止子视图释放自我?【英文标题】:How to prevent subview release self after call removeFromSuperview? 【发布时间】:2017-04-17 04:28:11 【问题描述】:

我想在单击按钮时更改两个子视图,子视图是由 StoryBoard 创建的,每个子视图都有一个按钮,单击该按钮将带来另一个子视图并隐藏当前的子视图。 但是我发现当一个子视图调用 removeFromSuperview() 时,它会自动释放,如果我以后想使用这个子视图,我需要一个 var 来指向它。 这是我的代码:

class ViewController: UIViewController 

    @IBOutlet weak var secondView: UIView!
    @IBOutlet weak var firstView: UIView!
    var temp1: UIView?
    var temp2: UIView?
    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        temp1 = firstView
        temp2 = secondView
        secondView.removeFromSuperview()
    
    @IBAction func moveToSecond(_ sender: UIButton) 
        firstView.removeFromSuperview()
        view.insertSubview(secondView, at: 0)
        secondView.isUserInteractionEnabled = true
    
    @IBAction func moveToFirst(_ sender: UIButton) 
        secondView.removeFromSuperview()
        view.insertSubview(firstView, at: 0)
        firstView.isUserInteractionEnabled = true
    

没有两个临时变量,子视图会在removeFromSuperview后释放,并导致下一个insertSubview崩溃,因为它是nil。 那么,如何防止子视图自动释放呢? 是否有另一种方法可以在 StoryBoard 优雅创建的两个子视图之间进行切换?

我的错误,我没有注意到outlet很弱,一切都是合理的,当removeFromSuperview时,没有给子视图留下任何优势,而是自动释放。

【问题讨论】:

尝试隐藏显示你的观点 【参考方案1】:

您可以使用@IBOutlet var secondView: UIView! 来创建视图的强引用。但是根据您的要求,我建议不要将其从超级视图中删除。相反,您应该在需要时隐藏和显示视图,如下所示。

class ViewController: UIViewController 

@IBOutlet var secondView: UIView!
@IBOutlet var firstView: UIView!
override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    secondView.isHidden = true

@IBAction func moveToSecond(_ sender: UIButton) 
    firstView.isHidden = true
    secondView.isHidden = false
    secondView.isUserInteractionEnabled = true

@IBAction func moveToFirst(_ sender: UIButton) 
    secondView.isHidden = true
    firstView.isHidden = false
    firstView.isUserInteractionEnabled = true


【讨论】:

谢谢,我明白了。【参考方案2】:

假设您的两个视图是一个在上面,具有相同的宽度和相同的高度。在 viewDidLoad 中。首先将 firstView 设置为前面,将 secondView 设置为后面。单击按钮后,我将 secondView 带到前面,将 firstView 带到后面,就像这样。

import UIKit

class ViewController1: UIViewController 

    @IBOutlet var secondView: UIView!
    @IBOutlet var firstView: UIView!

    override func viewDidLoad() 
        super.viewDidLoad()

        self.view.bringSubview(toFront: firstView)
        self.view.sendSubview(toBack: secondView)
    
    @IBAction func moveToSecond(_ sender: UIButton) 
        self.view.bringSubview(toFront: secondView)
        self.view.sendSubview(toBack: firstView)
    
    @IBAction func moveToFirst(_ sender: UIButton) 
        self.view.bringSubview(toFront: firstView)
        self.view.sendSubview(toBack: secondView)
    

如果您的两个子视图位于视图的不同位置。那么您需要在相应的按钮单击中隐藏替代视图

      class ViewController: UIViewController 

        @IBOutlet var secondView: UIView!
        @IBOutlet var firstView: UIView!
        override func viewDidLoad() 
            super.viewDidLoad()
            secondView.isHidden = true
            firstView.isUserInteractionEnabled = true
        
        @IBAction func moveToSecond(_ sender: UIButton) 
            firstView.isHidden = true
            secondView.isHidden = false
            secondView.isUserInteractionEnabled = true
        
        @IBAction func moveToFirst(_ sender: UIButton) 
            secondView.isHidden = true
            firstView.isHidden = false
            firstView.isUserInteractionEnabled = true
        

 

【讨论】:

虽然您回答提出了一种解决方法,但它并没有直接回答问题。 在问题中没有正确提及,视图是如何放置在主视图上的。所以基于两种情况我写了答案。谢谢

以上是关于调用removeFromSuperview后如何防止子视图释放自我?的主要内容,如果未能解决你的问题,请参考以下文章

UIView removeFromSuperview 正在调用 didMoveToSuperview

iOS SDK:ARC removeFromSuperview

如果从另一个类调用 removeFromSuperview 将不起作用

出口集合 removefromsuperview

性能优化之函数防抖动

removeFromSuperview 无法正常工作