在另一个ViewController中的ViewController之间显示和切换

时间:2018-12-28 15:08:40

标签: ios swift uiviewcontroller uitabbarcontroller uitabbar

由于我需要一些特定的功能,因此我基本上试图创建自定义的UITabBarController。 TabBar本身已经完成并且可以正常工作,但是我不知道如何在CustomTabBarViewController本身中显示ViewController。

假设我有以下方法:

func tabSelected(_ index: Int) {}

并通过tabbar.frame.size知道TabBar的高度,如何在调用tabSelected方法时实例化TabBar上方的两个ViewController并在它们之间切换?过渡动画会更好,但并不是必须的。

注意:为了避免进一步的混乱,我的TabBar不会从UITabBarController继承,而仅从常规UIViewController继承。

2 个答案:

答案 0 :(得分:1)

在这里我创建了示例项目: CustomTabBarViewController


  • 您应该具有子ViewController的容器视图
  • 然后您应该具有嵌入ViewControllers的数组
  • 您应该在中调用method CustomTabBarViewController会在其中更改ViewController 容器视图从VC数组到ViewController的索引,您将该索引作为此方法的参数传递

首先为TabBar按钮声明插座集合,并获取将在其中显示ViewController的容器视图的参考

@IBOutlet var tabBarButtons: [UIButton]!
@IBOutlet weak var container: UIView!

然后为标签栏项创建数组

var items: [UIViewController]?

接下来为控制器创建延迟变量

private lazy var aVC: A = {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    return storyboard.instantiateViewController(withIdentifier: "a") as! A
}()

private lazy var bVC: B = {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    return storyboard.instantiateViewController(withIdentifier: "b") as! B
}()

.......这可以通过创建根据VC的标识符返回ViewController的方法来简化

此后,将ViewControllers附加到您的items数组中,并且每个都添加为TabBarViewController的child

override func viewDidLoad() {
    super.viewDidLoad()
    items = [aVC, bVC]
    items!.forEach { addChild($0) }
}

继续声明用于设置ViewController的方法

private func setViewController(_ viewController: UIViewController) {
    items!.forEach { $0.view.removeFromSuperview(); $0.willMove(toParent: nil) }
    container.addSubview(viewController.view)
    viewController.view.frame = container.bounds
    viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    viewController.didMove(toParent: self)
}

现在为标签栏按钮添加操作并获取按钮索引。然后使用此索引调用您的tabSelected方法

@IBAction func buttonPressed(_ sender: UIButton) {
    if let index = tabBarButtons.index(of: sender) {
        tabSelected(index)
    }
}

tabSelected内部设置items中的VC,具体取决于发送方标签栏按钮的索引

func tabSelected(_ index: Int) {
    if let item = items?[index] {
        setViewController(item)
    }
}

最后在viewDidLoad中设置第一项

override func viewDidLoad() {
    ...
    tabSelected(0)
}

现在,您可以完全自定义ViewController并制作其他UITabBarController已知的史诗般的东西

答案 1 :(得分:1)

这是另一种方法:

1。。在您的CustomTabBarViewController中定义一个数组来保存ViewController:

var viewControllers: [UIViewController]

实例化视图控制器并将其添加到数组中

// If you're not using storyboard:
let homeViewController = HomeViewController()
// If using storyboard:
let searchViewController = storyboard.instantiateViewController(withIdentifier: "SearchViewController")

viewControllers = [homeViewController, searchViewController, ...]

2。。定义一个变量以跟踪所选的选项卡按钮:

var selectedIndex: Int = 0

3。。像这样实现您的tabSelected方法。我已经在代码中解释了每一行:

func tabSelected(_ index: Int) {
    let previousIndex = selectedIndex

    selectedIndex = index

    // Use previousIndex to access the previous ViewController from the viewControllers array.
    let previousVC = viewControllers[previousIndex]

    // Remove the previous ViewController
    previousVC.willMove(toParentViewController: nil)
    previousVC.view.removeFromSuperview()
    previousVC.removeFromParentViewController()

    // Use the selectedIndex to access the current ViewController from the viewControllers array.
    let vc = viewControllers[selectedIndex]

    // Add the new ViewController (Calls the viewWillAppear method of the ViewController you are adding)
    addChildViewController(vc)
    vc.view.frame = contentView.bounds

    // contentView is the main view above your tab buttons
    contentView.addSubview(vc.view)

    // Call the viewDidAppear method of the ViewController you are adding using didMove(toParentViewController: self)
    vc.didMove(toParentViewController: self)
}