UIViewController setView nil自动从superview中删除

时间:2015-05-24 22:45:49

标签: ios cocoa-touch uiviewcontroller uikit

在UIViewController上调用setView会自动从其超级视图中删除当前视图。我找不到这个记录。在我的情况下,我想在维护我的视图结构的同时动态交换UIViewController对象。我打算只是将视图重新链接到新控制器,但唉,这不起作用。

通常,从超级视图中自动删除视图似乎是一个明智的决定。文档应该反映这一点。

(对于任何人认为以这种方式交换视图控制器对象是一个非常糟糕的主意,让我补充说我正在交换的控制器是现有控制器的子类。这种方法非常适合添加功能视图是另一个视图的扩展。)

2 个答案:

答案 0 :(得分:0)

这就是我解决它的方法:

UIView *viewToKeep = self.viewController.view;
UIView *superview = viewToKeep.superview;
self.viewController.view = nil;  // removes the view from its superview

UIViewController *swapInViewController = [[UIViewController alloc] init];
swapInViewController.view = viewToKeep;
[superview addSubview: viewToKeep];
[viewToKeep applyConstraintsToFillSuperview];  // a helper to add auto layout constraints that make the view always fill it's parent
self.viewController = swapInViewController;

答案 1 :(得分:0)

这样做绝对违反了UIKit的内容,因此很可能是一个坏主意。

也就是说,这可以防止视图被自动删除,这意味着您无需使用addSubview将其放回原位。

只有你在下面看到的测试,告诫经纪人等等。在Swift中:

class View: UIView {
    var preventRemovalFromSuperView = false
    override func removeFromSuperview() {
        if !preventRemovalFromSuperView {
            super.removeFromSuperview()
        }
        preventRemovalFromSuperView = false
    }
}

let vc1 = UIViewController()
let vc2 = UIViewController()
let sv = UIView()
let v = View()

// Existing hierarchy
sv.addSubview(v)
vc1.view = v

// Swap view controllers
v.preventRemovalFromSuperView = true // Prevent automatic removal
vc1.view = nil // Prevent UIViewControllerHierarchyInconsistency exception
vc2.view = v

// Check that view was not automatically removed
v.isDescendantOfView(sv) // true