簡體   English   中英

在視圖控制器之間傳遞數據使用從導航控制器中嵌入的視圖到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中的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)

     }
}

這就是故事板的樣子:

在此輸入圖像描述

這是我的視圖控制器,您可以在其中檢查我是否向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.
    }

}

現在,您可以查看我的控制台和故事板: 在此輸入圖像描述

在此輸入圖像描述

來自Apple的UIViewController文檔:

var presentsViewController:UIViewController?

提供此視圖控制器的視圖控制器。

哪個對你有用,** 如果 **你試圖回到你的導航層次結構中,就像你引用SO帖子中的人一樣。

你想投所呈現的的SOURCEVIEWCONTROLLERVC SourceViewController作為一個UITabBarController ,其失敗草草收場,而就是為什么你從來不打你里面嵌套一個斷點if let的。

如果我們在文檔中查看下一個變量,我們可以看到一些東西將我們帶到我們呈現的UIViewController

var presentsViewController: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:中傳遞數據prepareForSegue:您實際上希望從segue.destination獲取UITabBarController 而且由於UITabBarControllerViewControllers屬性在准備segue時將為nil或空。 這是傳遞數據的糟糕方法。

您可能需要創建UITabBarController自定義子類,將其傳遞給變量,然后將該數據傳遞給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
    }
}

不要忘記將故事板的身份檢查器中的UITabBarController類更改為MyTabBarController

您需要更改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)

希望這個解決方案有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM