简体   繁体   中英

Passing data between view controllers when using a tab bar controller

I am having trouble passing data between view controllers.

I tried using prepare(for: segue) and setting a property on the destination view controller, but I set breakpoints while debugging the app and that function doesn't seem to get called when the user clicks the buttons on the tab bar at the bottom of the navigation controller.

This is the main way users navigate through my app, so I'm wondering if there is another way to do it.

I know you can use segue.identifier to determine which segue is being triggered, but I don't see an identifier property on these segues.

When I click on the line that connects the navigation controller to the view controller there is no identifier property on the attributes pane.

The storyboard calls it a "relationship segue" and it has a "selector" property (see attached screen shot).

Is this what I use to identify which tab bar button the user clicked?

And how would I trigger the setting of the property if prepare(for: segue) isn't called?

故事板布局

Your question title asks about navigation controller, but the rest of your question and the image is about tab bar controllers, so I'll assume that is what you are asking about.

There are two different cases here:

  1. When the various contained view controllers are first created; This is handled by the relationship segues, but these are not segues that result in prepare(for:sender:) being called. These "segues" just represent the relationships in the storyboard that enable the UITabBarController to load the embedded view controllers.
  2. When the user switches between the different tabs - This seems to be way you are asking about. This is not handled using segues, so putting code in prepare(for:sender:) won't help you.

What you can do is create a subclass of UITabViewController and use that in place of the standard UITabViewController in your storyboard.

Now, you can override viewDidLoad in your subclass and access the embedded view controllers via self.viewControllers - This gives you initial access to those view controllers so that you can customise their initial state.

What about handling tab switches?

UITabViewController conforms to UITabBarDelegate . This means your subclass can implement [tabBar(_:didSelect)] ( https://developer.apple.com/documentation/uikit/uitabbardelegate/1623463-tabbar ). This function is called each time the user selects a tab. In this function you can use the selectedViewController property to get the newly selected view controller, cast it to the appropriate type and set its properties as required.


class MyTabBarController: UITabBarController {

    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    
        if let vc = self.selectedViewController as? Tab0ViewController {
            vc.someProperty=someValue
        } else if let vc = self.selectedViewController as? Tab1ViewController {
            vc.someProperty=someValue
        }
    }
}

However, this may not be necessary if you set up your view controllers to use a shared data model.

Your view controllers can observe the model and whenever your model is updated, those changes can be communicated to the various view controllers through some other method; You could use Combine or Notifications, for example.

Then, when the user switches tabs the view controller is already showing the right information.

It depends on exactly what you are trying to achieve.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM