Domanda

I have this UISplitViewController which both master and detail VCs are UINavigationController subclasses. The two are supposed to work "in synchrony", ie, when one pushes a new VC, the second has to push one too. When one pops, the other has to pop too. One always triggers the same action to the other.

I'm already able to handle the pushing part of the problem, since the push functions are explicit in each class I use.

Popping, on the other hand, has been a big problem. The action is triggered when user presses the back button, and I don't know how to detect this event. One possible solution is detecting the event.

Another solution I thought of was to override UINavigationController's - popViewControllerAnimated:, making one class pop the other class, just like this:

// On DetailNav
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
  // Code to make MasterNav pop

  return [super popViewControllerAnimated:animated];
}

// On MasterNav
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
  // Code to make DetailNav pop

  return [super popViewControllerAnimated:animated];
}

I didn't bother adding the full code because this is enough to notice that this approach would cause an infinite-loop, eventually popping both NavControllers to their roots (and then possibly crashing).

What is the best way to achieve the desired behavior?

È stato utile?

Soluzione 2

I found the solution on @Chrizzz's answer to another question.

Basically you need two subclasses of UINavigationController, one for master and one for detail.

In both subclasses, you must include UINavigationBarDelegate and set the delegate to self . Then include the following method:

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
  [[[[self splitViewController] viewControllers][0 or 1] navigationController] performSelector:@selector(popViewControllerAnimated:) withObject:@YES afterDelay:0];
  return YES;
}

In the master, you'll want to pop the detail VC, so put a 1 on the index.
In the detail, you'll want to pop the master VC, so put a 0 on the index.

This solution allows you to run a routine before popping the view controller.

Update
I was getting some NavigationBar errors getting corrupted such as nested pop animation can result in corrupted navigation bar. So instead of directly calling popViewControllerAnimated: I called performSelector: with zero delay and nothing bad happens now when I pop my views.

Altri suggerimenti

For iOS 5+, - (BOOL)isMovingFromParentViewController does the trick:

// Use this in the detail VC
- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];

  if (self.isMovingFromParentViewController) {
    // the view is being popped. 
    // so also pop the master VC 
  }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top