我想将子视图控制器添加到UINavigationController's
视图中。我有这样的等级
NavigationController
-> View(drawer
)-> View(contentContainer
)->子视图控制器应固定到contentContainer
但是由于某种原因,它忽略了约束,所以我得到了奇怪的结果。请查看屏幕截图,drawer
为绿色,contentContainer
为黄色,并且子控制器几乎位于屏幕外部,并且框架的高度为0。
关键代码位于drawerContentController
didSet
和setupView
方法中。请注意,我使用SnapKit进行约束,但是通过传统地设置NSLayoutConstraints
class NavigationController: UINavigationController {
private var drawerHeightConstraint: Constraint!
fileprivate lazy var drawer = UIView()
private lazy var contentContainer = UIView()
var drawerContentController: UIViewController? {
didSet {
guard let new = drawerContentController else {
oldValue?.removeFromParent(animated: true)
return
}
if let old = oldValue {
old.removeFromParent(animated: true) { _ in
self.add(child: new, superview: self.contentContainer, animated: true, completion: nil)
}
} else {
add(child: new, superview: contentContainer, animated: true, completion: nil)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
setupView()
}
private func setupView() {
view.addSubview(drawer)
drawer.backgroundColor = .green
drawer.snp.makeConstraints { make in
make.leading.bottom.trailing.equalToSuperview()
drawerHeightConstraint = make.height.equalTo(360).constraint
}
let blur = UIBlurEffect(style: .default)
let visualView = UIVisualEffectView(effect: blur)
drawer.addSubview(visualView)
visualView.pinToSuperView()
contentContainer.backgroundColor = .yellow
drawer.addSubview(contentContainer)
contentContainer.snp.makeConstraints { make in
make.edges.equalTo(drawer.safeAreaLayoutGuide)
}
}
func add(child controller: UIViewController, superview: UIView? = nil, animated: Bool, completion: ((Bool) -> Void)? = nil) {
controller.willMove(toParent: self)
addChild(controller)
controller.view.alpha = 0
(superview ?? view).addSubview(controller.view)
controller.view.pinToSuperView()
UIView.animate(withDuration: animated ? 0.3 : 0, animations: {
controller.view.alpha = 1
}) { finished in
controller.didMove(toParent: self)
completion?(finished)
}
}
}
extension UIView {
func pinToSuperView() {
snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
}
当我将一个简单的UIView添加到contentContainer时,它会按预期工作
var drawerContentController: UIViewController? {
didSet {
let v = UIView()
v.backgroundColor = .purple
contentContainer.addSubview(v)
v.pinToSuperView()
}
}
答案 0 :(得分:-1)
好的,我“解决了”问题。
似乎UINavigationController
不喜欢添加子视图控制器。如屏幕截图所示,添加子控制器后,导航控制器的整个视图层次结构都被破坏了。在第二张屏幕截图中,表视图控制器(白色视图)正确显示,但在第一种情况下,它甚至不在视图层次结构中!
因此,应避免将子视图控制器不直接添加到UINavigationController
中,最后这不是正常的UIViewController
,甚至没有正常的UIView
。我添加了另一个UIViewController
作为UINavigationController
的容器,并向其添加了子控制器。现在可以正常工作了。