在视图控制器之间传递数据使用从导航控制器中嵌入的视图到tabbarcontroller的segue

问题描述 投票:5回答:3

我有两个视图,我想将数据从一个视图传递到下一个视图。第一个视图是我有数据,我想传递给下一个视图让我们称之为SourceViewController。然而SourceViewController嵌入在NavigationViewController中,secondViewController让我们称之为DestinationViewControllerTabViewController中的第一个View。

我试图使用this question的答案,它无法超越导航视图,它只是跳过了整个逻辑。

这是我的代码:

    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)

     }
}

这就是故事板的样子:

enter image description here

swift storyboard segue uistoryboardsegue
3个回答
4
投票

这是我的视图控制器,您可以在其中检查我是否向tabbar第一个viewcontroller发送5:

   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
    }
}

现在您可以检查我的第一个视图控制器,您可以在哪里检查我们获得的值。

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.
    }

}

现在,您可以查看我的控制台和故事板:enter image description here

enter image description here


3
投票

来自Apple的UIViewController文档:

是presentViewController:UIViewController?

提供此视图控制器的视图控制器。

哪个对你有用,**如果**你试图回到你的导航层次,就像SO post you referenced中的那个人一样。

你正在尝试将你的SourceViewController的VC提供的SOURCEVIEWCONTROLLER作为UITabBarController,它失败了,这就是为什么你从来没有在嵌套的if let中打破断点。

如果我们在docs中查看下一个变量,我们可以看到一些东西将我们带到我们呈现的UIViewController

presentViewController:UIViewController?

视图控制器,由此视图控制器或视图控制器层次结构中的一个祖先呈现。

所以现在回顾一下解决困境所需的代码。我会给你你发布的相同代码,但在评论中修复我的动词时态:

 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
        }

    }

当英语语言哄骗你时,不是很沮丧吗?

编辑:

由于您在prepareForSegue:中传递数据,您实际上想要从UITabBarController获取segue.destination。而且由于UITabBarControllerViewControllers财产在为segue做准备时将为零或空。这是传递数据的糟糕方法。

您可能需要创建UITabBarController的自定义子类,将其传递给变量,然后将该数据传递到viewControllers中的viewDidLoad

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
    }
}

别忘了将故事板的身份检查员中的UITabBarController班改为MyTabBarController


2
投票

您需要更改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 + Navigation堆栈中获取它。

希望这会有所帮助!

编辑:

let destinationVC = segue.destination as? HomeViewController
Print(destinationVC)
© www.soinside.com 2019 - 2024. All rights reserved.