我有一个UITabController Main,它有两个UIViewControllers,A和B.在storyboard中。每个控制器都有一个相应的swift类,Main,A,B
Main.swift是UITabController的子类,是UITabBarControllerDelegate的委托。在viewDidLoad中,它设置了.delegate = self。
在Main的func tabBarController(_ tabBarController:UITabBarController,didSelect viewController:UIViewController)中捕获选定的选项卡,并采取措施设置一些我希望传递给所选viewController变量Y的数据值。
在ViewController类A和B中,有一个变量Y的var声明。
在每个ViewController A和B中,在viewWillAppear中,我从此变量Y填充本地自定义视图出口。
它不起作用的原因是由于事件处理的顺序。
我假设当我单击选项卡时,首先处理Main的tabBarController函数,然后处理所选的相应viewController的viewWillAppear。事实并非如此。
显然,首先执行所选的(A或B)viewController的viewWillAppear,然后激活Main的tabBarController。这当然会导致问题,因为我显示由Y填充的出口然后我填充Y ...
这种使主要填充A或B包含一些数据的技术是首选,因为A和B不应该彼此了解任何事情。但是Main对A和B都非常了解。我真的不想做单例/全局数据传递 - 我更喜欢干净利落地处理它。
有关如何更正此事件序列的任何建议或建议另一种(适当的MVC)技术吗?
我的目标:我想将一些数据传递给所选标签下的视图层次结构,并让调用者进行传递。接收者视图层次结构应该忽略它接收数据的方式。
(我有一个丑陋的解决方法,我会重新启动viewWillappear,但基本上这会导致愚蠢的流程:A.viewWillAppear - > Main.tabBarController - >强制另一个A.viewWillAppear)
非常感谢。
代码(简化 - 现在这是一个已解决的工作示例)
class MainController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self;
}
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print ("tabBarController didSelect")
let viewController = viewControllers![self.selectedIndex]
if let vc = viewController as? AViewController {
vc.Y = "some valuable data"
}
else if let vc = viewController as? BViewController {
vc.Y = "some valuable data"
}
}
}
class AViewController: UIViewController {
@IBOutlet weak var YTextField: UITextField!
var Y: String = ""
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
print ("viewWillAppear A")
super.viewWillAppear(animated)
YTextField.text = self.Y
}
}
class BViewController: UIViewController {
@IBOutlet weak var YTextField: UITextField!
var Y: String = ""
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
print ("viewWillAppear B")
super.viewWillAppear(animated)
YTextField.text = self.Y
}
}
答案 0 :(得分:0)
您正在使用:
// this is called when the tab's ViewController is selected (*after* the tab item is selected (tapped))
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { ... }
当您想要使用时:
// this is called *when* the tab item is selected (tapped)
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { ... }
以下是对您的示例的修改:
import UIKit
class MainViewController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self;
}
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
let n = self.selectedIndex
if let tabControllers = viewControllers {
if let _ = tabControllers[n] as? AViewController {
// *current* VC is AViewController
if let vcB = tabControllers[n + 1] as? BViewController {
vcB.Y = "some valuable data from A"
}
}
else if let _ = tabControllers[n] as? BViewController {
// *current* VC is BViewController
if let vcA = tabControllers[n - 1] as? AViewController {
vcA.Y = "some valuable data from B"
}
}
}
}
}
class AViewController: UIViewController {
@IBOutlet weak var YTextField: UITextField!
var Y:String = ""
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
YTextField.text = Y
}
}
class BViewController: UIViewController {
@IBOutlet weak var YTextField: UITextField!
var Y:String = ""
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
YTextField.text = Y
}
}
您需要进行一些额外的处理/检查,以确保您获得所需的标签。您可能想要在MainViewController
上的didSelect item
内设置一个变量,然后在" target"内设置变量。查看didSelect viewController
上的控制器。