创建我自己的导航栏

时间:2018-01-16 07:34:42

标签: ios swift

我有一个父viewController说mainVC。 在底部有一个工具栏子视图 - UIView,带有按钮。

当我按下这些按钮时,我想在3个控制器之间推送/转换,但我想始终将mainVC上的这个底部工具栏保持在最顶层

如果我只是推一个新的控制器,它将覆盖我的mainVC - 因此工具栏。

如何以编程方式 获得此效果?

2 个答案:

答案 0 :(得分:3)

一种方法是使用一个视图控制器,工具栏作为唯一的子视图。您可以调用此MyToolBarController。然后,将容器视图添加到MyToolBarController

enter image description here

容器视图由其他视图控制器控制,因此您可以让3个VC中的一个控制它。当您呈现新VC时,它仍应显示在容器视图中。由于这一切都发生在MyToolBarController,工具栏仍然会在那里。

答案 1 :(得分:1)

我通常做的是嵌入一个新的视图控制器。基本上,您通过某个视图将视图控制器的实例附加到另一个视图控制器......

您需要在父级上调用addChildViewController,在转换时willMovedidMove会在新的视图控制器上触发相应的事件。否则,您需要将视图控制器的视图作为子视图添加到目标视图。

检查以下哪个是我正在使用的剥离版本:

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。在您的情况下,这是您的导航控制器,然后将在内部工作。

剥离的部分是我删除了与动画相关的所有内容。因此,我很确定在那里还有一些额外的布局调用。