我有一个父viewController说mainVC
。
在底部有一个工具栏子视图 - UIView
,带有按钮。
当我按下这些按钮时,我想在3个控制器之间推送/转换,但我想始终将mainVC上的这个底部工具栏保持在最顶层。
如果我只是推一个新的控制器,它将覆盖我的mainVC - 因此工具栏。
如何以编程方式 获得此效果?
答案 0 :(得分:3)
一种方法是使用一个视图控制器,工具栏作为唯一的子视图。您可以调用此MyToolBarController
。然后,将容器视图添加到MyToolBarController
。
容器视图由其他视图控制器控制,因此您可以让3个VC中的一个控制它。当您呈现新VC时,它仍应显示在容器视图中。由于这一切都发生在MyToolBarController
,工具栏仍然会在那里。
答案 1 :(得分:1)
我通常做的是嵌入一个新的视图控制器。基本上,您通过某个视图将视图控制器的实例附加到另一个视图控制器......
您需要在父级上调用addChildViewController
,在转换时willMove
和didMove
会在新的视图控制器上触发相应的事件。否则,您需要将视图控制器的视图作为子视图添加到目标视图。
检查以下哪个是我正在使用的剥离版本:
class ContentControllerView: UIView {
@IBOutlet weak var parentViewController: UIViewController?
private(set) var currentController: UIViewController?
private var addedConstraints: [NSLayoutConstraint] = [NSLayoutConstraint]()
func setViewController(controller: UIViewController?) {
guard let parentViewController = parentViewController else {
print("ContentControllerView error: You need to set a parentViewController to add a new view controller")
return
}
if controller?.view != currentController?.view {
currentController?.willMove(toParentViewController: nil) // Notify the current controller it will move off the parent
controller?.willMove(toParentViewController: parentViewController) // Notify the new controller it will move to the parent
if let controller = controller {
parentViewController.addChildViewController(controller) // Add child controller
}
let toRemove = addedConstraints
addedConstraints.removeAll()
controller?.view.translatesAutoresizingMaskIntoConstraints = false // Disable this to add custom constraints
if let controller = controller {
self.addSubview(controller.view) // Add as subview
addedConstraints.append(NSLayoutConstraint(item: self, attribute: .left, relatedBy: .equal, toItem: controller.view, attribute: .left, multiplier: 1.0, constant: 0.0))
addedConstraints.append(NSLayoutConstraint(item: self, attribute: .right, relatedBy: .equal, toItem: controller.view, attribute: .right, multiplier: 1.0, constant: 0.0))
addedConstraints.append(NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: controller.view, attribute: .top, multiplier: 1.0, constant: 0.0))
addedConstraints.append(NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: controller.view, attribute: .bottom, multiplier: 1.0, constant: 0.0))
// Assign new constraints
self.addConstraints(addedConstraints)
}
controller?.view.layoutIfNeeded()
self.layoutIfNeeded()
toRemove.forEach { self.removeConstraint($0) }
self.currentController?.view.translatesAutoresizingMaskIntoConstraints = true
controller?.view.frame = CGRect(x: 0.0, y: 0.0, width: self.frame.size.width, height: self.frame.size.height)
self.currentController?.view.removeFromSuperview()
self.currentController?.didMove(toParentViewController: nil) // Notify the current controller it did move off the parent
self.currentController?.removeFromParentViewController() // remove the current controller from parrent
controller?.didMove(toParentViewController: parentViewController) // Notify the new controller it did move to the parent
self.currentController = controller
self.superview?.setNeedsLayout()
(self.superview ?? self).layoutIfNeeded()
}
}
func clear() {
guard currentController != nil else {
return
}
setViewController(controller: nil)
}
}
您可以在代码或Storyboard中使用此视图。请注意,必须设置parentViewController
。因此,在故事板中,您可以在条形图上方添加正常UIView
,然后将其类设置为ContentControllerView
。然后按住Ctrl键并从中拖动到视图控制器并选择parentViewController
。
然后在代码中,您可以使用所需的视图控制器在其上调用setViewController
。在您的情况下,这是您的导航控制器,然后将在内部工作。
剥离的部分是我删除了与动画相关的所有内容。因此,我很确定在那里还有一些额外的布局调用。