在另一个 ViewController 中的 ViewController 之间显示和切换
Displaying and switching between ViewControllers in another ViewController
我基本上是在尝试创建一个自定义的 UITabBarController,因为我需要一些特定的功能。 TabBar 本身已经完成并可以正常工作,但我不太清楚如何在此 CustomTabBarViewController
本身中显示 ViewControllers。
假设我有以下方法:
func tabSelected(_ index: Int) {}
并且通过tabbar.frame.size
知道我的TabBar的高度,我如何在TabBar上方实例化两个ViewControllers并在调用tabSelected
方法时在它们之间切换?过渡动画会更好,但不是必需的。
注意:我的 TabBar 不继承自 UITabBarController
,仅继承自常规 UIViewController
,以避免进一步混淆。
这里我创建了示例项目:
CustomTabBarViewController
- 您应该有 child ViewControllers
的容器视图
- 那么你应该有嵌入 ViewControllers
的数组
- 你应该在
CustomTabBarViewController
里面改成ViewController
容器视图 ViewController 来自 VC 数组的索引,您将其作为此方法的参数传递
首先为您的 TabBar 按钮声明 outlet 集合,并获取将显示 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
}()
... 这可以通过创建方法来简化,其中 returns ViewController 取决于 VC 的标识符
之后,将 ViewControllers 附加到您的 items
数组,并将每个添加为 TabBarViewController
的 child
override func viewDidLoad() {
super.viewDidLoad()
items = [aVC, bVC]
items!.forEach { addChild([=13=]) }
}
继续声明设置方法ViewController
private func setViewController(_ viewController: UIViewController) {
items!.forEach { [=14=].view.removeFromSuperview(); [=14=].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. 在你的 CustomTabBarViewController
中定义一个数组来保存 ViewControllers:
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)
}
我基本上是在尝试创建一个自定义的 UITabBarController,因为我需要一些特定的功能。 TabBar 本身已经完成并可以正常工作,但我不太清楚如何在此 CustomTabBarViewController
本身中显示 ViewControllers。
假设我有以下方法:
func tabSelected(_ index: Int) {}
并且通过tabbar.frame.size
知道我的TabBar的高度,我如何在TabBar上方实例化两个ViewControllers并在调用tabSelected
方法时在它们之间切换?过渡动画会更好,但不是必需的。
注意:我的 TabBar 不继承自 UITabBarController
,仅继承自常规 UIViewController
,以避免进一步混淆。
这里我创建了示例项目: CustomTabBarViewController
- 您应该有 child ViewControllers 的容器视图
- 那么你应该有嵌入 ViewControllers 的数组
- 你应该在
CustomTabBarViewController
里面改成ViewController 容器视图 ViewController 来自 VC 数组的索引,您将其作为此方法的参数传递
首先为您的 TabBar 按钮声明 outlet 集合,并获取将显示 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
}()
... 这可以通过创建方法来简化,其中 returns ViewController 取决于 VC 的标识符
之后,将 ViewControllers 附加到您的 items
数组,并将每个添加为 TabBarViewController
child
override func viewDidLoad() {
super.viewDidLoad()
items = [aVC, bVC]
items!.forEach { addChild([=13=]) }
}
继续声明设置方法ViewController
private func setViewController(_ viewController: UIViewController) {
items!.forEach { [=14=].view.removeFromSuperview(); [=14=].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. 在你的 CustomTabBarViewController
中定义一个数组来保存 ViewControllers:
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)
}