将视图控制器添加到容器视图覆盖视图

时间:2016-11-16 16:14:14

标签: ios swift

我尝试过关注SO上的大量示例和其他questions。正在添加视图控制器,但它将视图容器放入视图而不是视图容器。这是我的意思。

enter image description here

我在主视图控制器上有一个标签栏和一个容器视图。当点击标签栏上的项目时,它应该抓住控制器并将其加载到容器视图中。这是我如何做的代码。

@IBOutlet weak var tabBar: UITabBar!
@IBOutlet weak var containerView: UIView!
var currentViewController: UIViewController!
var radarViewController: UIViewController!

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    let storyboard = self.storyboard
    let currentViewController = storyboard?.instantiateViewController(withIdentifier: "WeatherCurrentViewController") as! WeatherCurrentViewController
    self.currentViewController = UINavigationController(rootViewController: currentViewController)
    let radarViewController = storyboard?.instantiateViewController(withIdentifier: "WeatherRadarViewController") as! WeatherRadarViewController
    self.radarViewController = UINavigationController(rootViewController: radarViewController)
}
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    if item.tag == 1 {
        containerView.addSubview(currentViewController!.view)
        currentViewController.didMove(toParentViewController: self)
    }

    if item.tag == 2 {
        containerView.addSubview(radarViewController!.view)
        radarViewController.didMove(toParentViewController: self)
    }
}

这是Swift 3.我不知道我做错了什么。任何帮助表示赞赏。

更新

虽然我经常在经过多次更改/尝试后无法以编程方式切换视图,但我确实找到了另一种使用具有多个视图容器的segue的方法(here。不是理想的,因为它会占用更多的内存,但它的工作原理。

1 个答案:

答案 0 :(得分:0)

视图控制器只是UIView的包装器。因此,最后您将始终拥有作为子视图添加到容器视图的控制器视图。

关键是你仍然会获得视图控制器的所有通知,例如旋转变化,布局......

我使用的是一个UIView子类。它看起来像这样:

import UIKit

class ContentControllerView: UIView {

    weak var parrentViewController: UIViewController?
    private(set) var currentController: UIViewController?

    func setViewController(controller: UIViewController) {
        guard let parrentViewController = parrentViewController else {
            print("ContentControllerView error: You need to set a parrentViewController 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: parrentViewController) // Notify the new controller it will move to the parent
            parrentViewController.addChildViewController(controller) // Add child controller
            currentController?.view.removeFromSuperview()
            currentController?.didMove(toParentViewController: nil) // Notify the current controller it did move off the parent

            controller.view.translatesAutoresizingMaskIntoConstraints = false // Disable this to add custom constraints
            self.addSubview(controller.view) // Add as subview
            // Assign new constraints
            self.addConstraint(NSLayoutConstraint(item: self, attribute: .left, relatedBy: .equal, toItem: controller.view, attribute: .left, multiplier: 1.0, constant: 0.0))
            self.addConstraint(NSLayoutConstraint(item: self, attribute: .right, relatedBy: .equal, toItem: controller.view, attribute: .right, multiplier: 1.0, constant: 0.0))
            self.addConstraint(NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: controller.view, attribute: .top, multiplier: 1.0, constant: 0.0))
            self.addConstraint(NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: controller.view, attribute: .bottom, multiplier: 1.0, constant: 0.0))

            self.layoutIfNeeded()

            currentController?.removeFromParentViewController() // remove the current controller from parrent
            controller.didMove(toParentViewController: parrentViewController) // Notify the new controller it did move to the parent

            currentController = controller
        }
    }

}

视图可以添加到故事板中,但是然后在您需要分配视图控制器的代码中添加:

self.contentControllerView.parrentViewController = self
self.contentControllerView.setViewController(controller: controller)