tags:

views:

1389

answers:

1

Trying to mimic/copy the built-in address book, specifically the behavior when editing a contact or viewing an existing contact's Info from inside the Phone app. When you navigate to another tab, the editing state is reset and the "New Contact" or "Info" view is popped so that when you come back to the Contacts tab, you are back at the root table view.

I have most of this working inside viewWillDisappear using setEditing: and popToViewController: however I get strange behavior when the user navigates from the Info view to the table view using the back button. Even if I pop to the root table view controller, it seems to be using the default UITableViewController class and not my subclass (e.g. standard selection behaviors instead of my overrides to push the detail view.)

Any hints? IPD

Here's some code to illustrate:

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    // This is to clean up from the colored bar in detail view
    self.navigationController.navigationBar.tintColor = nil;

    // These are to match the behaviour of Contacts app
    [self setEditing:NO animated:NO];

    // This is the tricky part: works when switching tabs, but not when back button was going to pop anyway!!
    [self.navigationController popToViewController:rootViewControllerForTab animated:NO];
}
+2  A: 

The -viewWillDisappear: method is not the best place for modifying the view controller stack for your navigationController because it is triggered both when you switch tabs and when a view is pushed on top of it.

I played around with this a bit and found that the best place for this is in the -[UITabBarControllerDelegate tabBarController:didSelectViewController:] method. So, first you need to designate an object to be the delegate for your tab bar (I used the app delegate). Bind the delegate property of your UITabBarController to an object implementing the UITabBarControllerDelegate protocol in code or in Interface Builder.

Then, implement the -tabBarController:didSelectViewController: method. The trick now is how to tell when your "address book" tab is being switched to. I kept track of the view controller for the tab in question using a property of type UINavigationController (the root view controller for the tab). After binding the tab1NavController property to the actual instance using Interface Builder, it can be used to compare to the viewController parameter to see what tab was just selected.

@interface Pop2RootTabSwitchAppDelegate : NSObject 
    <UIApplicationDelegate, UITabBarControllerDelegate> {
  UINavigationController *tab1NavController;
}
@property (nonatomic, retain) IBOutlet UINavigationController *tab1NavController;
@end

@implementation Pop2RootTabSwitchAppDelegate

- (void)tabBarController:(UITabBarController *)tabBarController 
  didSelectViewController:(UIViewController *)viewController {
   NSLog(@"[%@ tabBarController:%@  didSelectViewController:%@]", [self class], 
       tabBarController, viewController);
   if (viewController == tab1NavController) {
       NSLog(@"viewController == tab1NavController");
       [tab1NavController popToRootViewControllerAnimated:NO];
   }
}
phatblat
That's the winner... thanks! (I had been focused on cleaning state on exit and never considered setting state on enter.)
iPhoneDollaraire