【问题标题】:UIViewController setView nil automatically removes from superviewUIViewController setView nil 自动从 superview 中移除
【发布时间】:2015-05-24 22:45:48
【问题描述】:
在 UIViewController 上调用 setView 会自动从其父视图中删除当前视图。我找不到这个记录。在我的情况下,我想动态地将 UIViewController 对象交换为另一个对象,同时保持我的视图结构。我正计划将视图重新链接到新控制器,但可惜,这不起作用。
一般来说,自动从其父视图中删除视图似乎是一个明智的决定。文档应该反映这一点。
(对于任何认为以这种方式交换视图控制器对象是一个非常糟糕的主意的人,让我补充一下,我正在交换的控制器是现有控制器的子类。这种方法非常适合添加功能到一个视图是另一个视图的扩展。)
【问题讨论】:
标签:
ios
cocoa-touch
uiviewcontroller
uikit
【解决方案1】:
我就是这样解决的:
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;
【解决方案2】:
这样做肯定违背了 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