【问题标题】:Why is UIView removed from heirarchy after presenting view controller?为什么在呈现视图控制器后 UIView 从层次结构中删除?
【发布时间】:2017-11-24 23:16:40
【问题描述】:

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

该属性仍处于设置状态,但已从视图层次结构中移除。

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

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. 我认为这就是问题所在。你可能想要这个:stackoverflow.com/questions/4425939/can-uiview-be-copied
  • 嗯,有道理。有什么建议可以使这项工作正常进行吗?
  • 我用一个可能的解决方案编辑了我之前的评论。但我会使用一种方法来创建带有所有自定义的 headerView 并调用它。
  • 太棒了。看起来我只需要为我的标题制作一个工厂。谢谢!
  • @Larme,你打败了我。您应该发表您的评论作为答案。事实上,这是正确的答案。

标签: ios swift explain


【解决方案1】:

-addSubview(_:)的文档:

视图只能有一个超级视图。如果视图已经有一个超级视图并且该视图不是接收者,则此方法会删除先前的 在将接收器设置为新的超级视图之前的超级视图。

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

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

如果你真的想“复制”视图,可以查看that answer。由于UIView 不符合NSCopying,他们的技巧是“存档/编码”它,因为它符合NSCoding,复制该存档,然后“解压/解码”它的副本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多