为什么在呈现视图控制器后 UIView 从层次结构中删除?

Why is UIView removed from heirarchy after presenting view controller?

好吧,我只是 运行 遇到了一些奇怪的事情。我的应用程序控制器依赖项将视图 (header) 注入视图控制器。该视图控制器以模态方式呈现另一个视图控制器,并且依赖项注入它自己的 header 以供呈现视图控制器使用。但是当它出现时,第一个控制器的 header 消失了。

属性 仍然设置,但已从视图层次结构中删除。

我在新的单视图项目中重现了这个问题:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = .white

        let button = UIButton(frame: CGRect(x: 0, y: 20, width: 100, height: 50))
        button.setTitle("Click Me!", for: .normal)
        button.addTarget(self, action: #selector(self.segue), for: .touchUpInside)
        button.backgroundColor = .black
        button.setTitleColor(.lightGray, for: .normal)

        self.view.addSubview(button)
    }

    func segue() {
        let view = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
        view.backgroundColor = .lightGray

        let firstVC = FirstViewController()
        firstVC.sharedView = view

        present(firstVC, animated: false)
    }
}

class FirstViewController: UIViewController {
    var sharedView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white

        self.view.addSubview(self.sharedView)

        let button = UIButton(frame: CGRect(x: 0, y: 200, width: 100, height: 50))
        button.setTitle("Click Me!", for: .normal)
        button.addTarget(self, action: #selector(self.segue), for: .touchUpInside)
        button.backgroundColor = .black
        button.setTitleColor(.lightGray, for: .normal)

        self.view.addSubview(button)
    }

    func segue() {
        let secondVC = SecondViewController()
        secondVC.sharedView = self.sharedView

        present(secondVC, animated: true)
    }
}

class SecondViewController: UIViewController {
    var sharedView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white

        self.view.addSubview(self.sharedView)

        let button = UIButton(frame: CGRect(x: 0, y: 200, width: 100, height: 50))
        button.setTitle("Click Me!", for: .normal)
        button.addTarget(self, action: #selector(self.segue), for: .touchUpInside)
        button.backgroundColor = .black
        button.setTitleColor(.lightGray, for: .normal)

        self.view.addSubview(button)
    }

    func segue() {
        self.dismiss(animated: true)
    }
}

有人能解释一下这是怎么回事吗?为什么 sharedView 从 FirstViewController 中消失了?

-addSubview(_:) 的文档中:

Views can have only one superview. If view already has a superview and that view is not the receiver, this method removes the previous superview before making the receiver its new superview.

这应该可以解释您的问题。

我建议您创建一个方法,根据您的自定义样式生成一个 headerView(每次一个新的)。

如果你真的想"copy"查看,你可以检查that answer。由于 UIView 不符合 NSCopying,他们的技巧是 "archive/encode" 因为它符合 NSCoding,所以复制 存档,"unarchive/decode"它的副本。