tags:

views:

276

answers:

4

Here is my code:

SignupController* signupController = [[SignupController alloc] initWithNibName:@"SignupController" bundle:nil];
    [window addSubview:[navigationController view]];
    [window makeKeyAndVisible];

    self.navigationController.title = @"MyNavController";

    [self.navigationController pushViewController:signupController animated:YES];
    [signupController release];

Unfortunately for me calling pushViewController is not synchronous, so the next line ([signupController release]) is executed immediately.

I need to detect hen the signupController has popped back to the root so I can take the data from the signup controller and do a registration or login.

Any ideas?

Thanks

A: 

Implement the registration in -viewWillDisappear: in your SignupController. But you cannot stop the controller from disappearing if the login fails.

You may want to present SignupController as a model view controller instead, where the "back" button no longer show automatically, so you can control when to leave that page.

KennyTM
A: 

There are a few ways you could do this:

  1. Give the UINavigationController a delegate, and have the delegate respond to navigationController:willShowViewController:animated:. In that method, check and see if the view controller about to be shown is the first view controller in the navigation controller's viewControllers array. This has the disadvantage of not being able to distinguish between a popToRoot and a simple back action.
  2. Subclass UINavigationController and override the popToRoot method:

    - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated {
      //somehow notify (NSNotification, delegate, etc) that you're popping to root
      return [super popToRootViewControllerAnimated:animated];
    }
  3. Implement the viewWillAppear method in your root view's controller. This has the disadvantage of not being able to distinguish between the initial push, a popToRoot, and a simple back action.

Dave DeLong
I really like the idea of #2 (though I try to avoid subclassing in Cocoa whenever possible, natch). In my case, I push Table View Controllers onto the stack, not general VCs. I can certainly subclass UITableViewController, but that won't respond to popToRootViewControllerAnimated: in this case. Moreover, I need to distinguish between various actions (#1 and #3 in your list). Hmm, what to do. :\
Joe D'Andrea
+1  A: 

Use a delegate pattern to call back to main controller to let it know that the signup controller is about to exit. Copy the values from the signup controller before it gets released by the navigation controller.

// SignupController.h
@protocol SignupDelegate;
@interface SignupController : UIViewController {
    id <SignupDelegate> delegate;
    NSString *name;
}
@property (nonatomic, assign) id <SignupDelegate> delegate;
@property (nonatomic, retain) NSString *name;
@end
@protocol SignupDelegate
- (void) signupControllerDidFinish:(SignupController *)controller;
@end

// SignupController.m
@implementation SignupController
@synthesize delegate;
@synthesize name;

- (void) viewWillDisappear:(BOOL)animated {
    [self.delegate signupControllerDidFinish:self];
}
@end

// YourViewController.m
- (void) signupSelected {
    SignupController *signup = [[SignupController alloc] initWithNibName:NSStringFromClass([SignupController class]) bundle:nil];
    signup.delegate = self;
    [controller.navigationController pushViewController:signup animated:YES];
    [signup release];
}

- (void) signupControllerDidFinish:(SignupController *)signup {
    NSLog(@"Signup with name %@", signup.name);
}
Gerry
A: 

Not sure if I understood your question...

But if I did... why not use a BOOL isSigningUp.

On your root, on ViewDidLoad, you assign it NO.

When you push your signupController, you assign your BOOL to YES.

Then, on your root's viewWillAppear, you put...

if (isSigningUp == YES) {
  isSigningUp = NO;
  //do registration or login
}

It's easy, which means I probably didn't understood what you asked. If that's the case, sorry for taking your time.

All the best.

camilo