在视图控制器之间传递数据使用从导航控制器中嵌入的视图到 tabbarcontroller 的 segue
Passing Data between view Controllers Using a segue from a view embedded in a navigation controller to a tabbarcontroller
我有两个视图,我想将数据从一个视图传递到下一个视图。第一个视图是我想要传递给下一个视图的数据所在的地方,我们称之为 SourceViewController
。但是 SourceViewController
嵌入在 NavigationViewController
中,secondViewController 称其为 DestinationViewController
是 TabViewController
中的第一个视图。
我尝试使用 的答案,但它无法通过导航视图,它只是跳过了整个逻辑。
这是我的代码:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "loginSuccessSugue") {
if let tab = self.presentingViewController as? UITabBarController,
let nav = tab.viewControllers?[0] as? UINavigationController,
let destinationVC = nav.viewControllers.first as? HomeViewController {
destinationVC.currentBalance = serviceBalance
}
}
}
这是HomeViewController
:
class HomeViewController: UIViewController , UITableViewDelegate,UITableViewDataSource, UICircularProgressRingDelegate{
var currentBalance = 0.0
override func viewDidLoad() {
super.viewDidLoad()
circularBalance.maxValue = CGFloat(currentBalance)
print(currentBalance)
}
override func viewDidAppear(_ animated: Bool) {
print(currentBalance)
circularBalance.setProgress(value: CGFloat(currentBalance), animationDuration: 3)
}
}
故事板是这样的:
您需要更改 if()
条件代码。
使用下面的代码将使您的HomeViewController
进入segue的目的地。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "loginSuccessSugue") {
if let destinationVC = segue.destination as? HomeViewController {
destinationVC.currentBalance = serviceBalance
}
}
}
与 segue.destination
一样,您将获得 HomeViewController
,因此无需从 Tab + 导航 堆栈中获取。
编辑:
let destinationVC = segue.destination as? HomeViewController
Print(destinationVC)
希望此解决方案对您有所帮助!
来自 Apple 的 UIViewController
文档:
var presentingViewController: UIViewController?
The view controller that presented this view controller.
这对你很有用,** IF ** 你正试图回到你的导航层次结构中,就像 中的那个人一样。
您正在尝试将 SourceViewController
的 VC THAT PRESENTED SOURCEVIEWCONTROLLER 转换为 UITabBarController
,但失败得很惨,这就是为什么您永远不会在嵌套的 if let
中遇到断点。
如果我们在 docs 中从这个向下看下一个变量,我们可以看到一些东西将我们带到我们正在呈现的 UIViewController
:
var presentedViewController: UIViewController?
The view controller that is presented by this view controller, or one
of its ancestors in the view controller hierarchy.
所以现在检查一下解决困境所需的代码。我会给你你发布的相同代码,但在评论中修正我的动词时态:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "loginSuccessSugue") {
//ing -> ed
if let tab = self.presentingViewController as? UITabBarController,
let nav = tab.viewControllers?[0] as? UINavigationController,
let destinationVC = nav.viewControllers.first as? HomeViewController {
destinationVC.currentBalance = serviceBalance
}
}
当英语比 swift 更能骗你时,是不是很沮丧?
编辑:
由于您在 prepareForSegue:
中传递数据,因此您实际上想要从 segue.destination
中获取 UITabBarController
。由于 UITabBarController
的 ViewControllers
属性 将为 segue 做准备,因此将为 nil 或空。这是传递数据的糟糕方法。
您可能需要创建 UITabBarController
的自定义子 class,将变量传递给它,然后将该数据传递给 viewDidLoad
中的 viewControllers
。
class MyTabBarController: UITabBarController {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
var serviceBalance : Double?
override func viewDidLoad() {
super.viewDidLoad()
//Make sure vc is not null or empty before continuing.
guard let vcs = viewControllers, !vcs.isEmpty else {
return
}
if let navVC = vcs[0] as? UINavigationController, let destinationVC = navVC.viewControllers[0] as? UIViewController {
destinationVC.serviceBalance = destinationVC
}
}
}
已更新prepareForSegue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let tabBarVC = segue.destination as? MyTabBarController {
tabBarVC.serviceBalance = serviceBalance
}
}
不要忘记将 Storyboard 的身份检查器中的 UITabBarController
的 class 更改为 MyTabBarController
这是我的视图控制器,您可以在其中检查我是否先将 5 发送到标签栏 viewcontroller:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.performSegue(withIdentifier: "segueIdentifier", sender: self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let barViewControllers = segue.destination as! UITabBarController
let destinationNv = barViewControllers.viewControllers?[0] as! UINavigationController
let destinationViewController = destinationNv.viewControllers[0] as! FirstViewController
destinationViewController.currentBalance = 5
}
}
现在您可以检查我的 firstview 控制器,您可以在其中检查我们获得的值。
class FirstViewController: UIViewController {
var currentBalance = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
print(currentBalance)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
现在,您可以查看我的控制台和故事板:
我有两个视图,我想将数据从一个视图传递到下一个视图。第一个视图是我想要传递给下一个视图的数据所在的地方,我们称之为 SourceViewController
。但是 SourceViewController
嵌入在 NavigationViewController
中,secondViewController 称其为 DestinationViewController
是 TabViewController
中的第一个视图。
我尝试使用
这是我的代码:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "loginSuccessSugue") {
if let tab = self.presentingViewController as? UITabBarController,
let nav = tab.viewControllers?[0] as? UINavigationController,
let destinationVC = nav.viewControllers.first as? HomeViewController {
destinationVC.currentBalance = serviceBalance
}
}
}
这是HomeViewController
:
class HomeViewController: UIViewController , UITableViewDelegate,UITableViewDataSource, UICircularProgressRingDelegate{
var currentBalance = 0.0
override func viewDidLoad() {
super.viewDidLoad()
circularBalance.maxValue = CGFloat(currentBalance)
print(currentBalance)
}
override func viewDidAppear(_ animated: Bool) {
print(currentBalance)
circularBalance.setProgress(value: CGFloat(currentBalance), animationDuration: 3)
}
}
故事板是这样的:
您需要更改 if()
条件代码。
使用下面的代码将使您的HomeViewController
进入segue的目的地。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "loginSuccessSugue") {
if let destinationVC = segue.destination as? HomeViewController {
destinationVC.currentBalance = serviceBalance
}
}
}
与 segue.destination
一样,您将获得 HomeViewController
,因此无需从 Tab + 导航 堆栈中获取。
编辑:
let destinationVC = segue.destination as? HomeViewController
Print(destinationVC)
希望此解决方案对您有所帮助!
来自 Apple 的 UIViewController
文档:
var presentingViewController: UIViewController?
The view controller that presented this view controller.
这对你很有用,** IF ** 你正试图回到你的导航层次结构中,就像
您正在尝试将 SourceViewController
的 VC THAT PRESENTED SOURCEVIEWCONTROLLER 转换为 UITabBarController
,但失败得很惨,这就是为什么您永远不会在嵌套的 if let
中遇到断点。
如果我们在 docs 中从这个向下看下一个变量,我们可以看到一些东西将我们带到我们正在呈现的 UIViewController
:
var presentedViewController: UIViewController?
The view controller that is presented by this view controller, or one of its ancestors in the view controller hierarchy.
所以现在检查一下解决困境所需的代码。我会给你你发布的相同代码,但在评论中修正我的动词时态:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "loginSuccessSugue") {
//ing -> ed
if let tab = self.presentingViewController as? UITabBarController,
let nav = tab.viewControllers?[0] as? UINavigationController,
let destinationVC = nav.viewControllers.first as? HomeViewController {
destinationVC.currentBalance = serviceBalance
}
}
当英语比 swift 更能骗你时,是不是很沮丧?
编辑:
由于您在 prepareForSegue:
中传递数据,因此您实际上想要从 segue.destination
中获取 UITabBarController
。由于 UITabBarController
的 ViewControllers
属性 将为 segue 做准备,因此将为 nil 或空。这是传递数据的糟糕方法。
您可能需要创建 UITabBarController
的自定义子 class,将变量传递给它,然后将该数据传递给 viewDidLoad
中的 viewControllers
。
class MyTabBarController: UITabBarController {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
var serviceBalance : Double?
override func viewDidLoad() {
super.viewDidLoad()
//Make sure vc is not null or empty before continuing.
guard let vcs = viewControllers, !vcs.isEmpty else {
return
}
if let navVC = vcs[0] as? UINavigationController, let destinationVC = navVC.viewControllers[0] as? UIViewController {
destinationVC.serviceBalance = destinationVC
}
}
}
已更新prepareForSegue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let tabBarVC = segue.destination as? MyTabBarController {
tabBarVC.serviceBalance = serviceBalance
}
}
不要忘记将 Storyboard 的身份检查器中的 UITabBarController
的 class 更改为 MyTabBarController
这是我的视图控制器,您可以在其中检查我是否先将 5 发送到标签栏 viewcontroller:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.performSegue(withIdentifier: "segueIdentifier", sender: self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let barViewControllers = segue.destination as! UITabBarController
let destinationNv = barViewControllers.viewControllers?[0] as! UINavigationController
let destinationViewController = destinationNv.viewControllers[0] as! FirstViewController
destinationViewController.currentBalance = 5
}
}
现在您可以检查我的 firstview 控制器,您可以在其中检查我们获得的值。
class FirstViewController: UIViewController {
var currentBalance = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
print(currentBalance)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
现在,您可以查看我的控制台和故事板: