开发者

How to do two UINavigationController opertaion from the same method?

Often I find myself need to dismiss the current modal view controller and then immediately push another view controller (so imagine something sliding down and then sliding right). What is a clever way to do this?

If you attempt to do these two operations all in one go, only the first one is carried out, the second one is ignored.

-(void)dismissThenPush{
[self.navigationController dismissModalViewControllerAnimated:TRUE]; //works
[self.navigationController pushViewController:controller animated:TRUE];    //ignored
}

For the past 12 months, what I do is set some global flag开发者_如何学JAVA, and have the original controller check for this flag in the viewDidAppear method and then call a pushViewController method. But I'm tired of this hack, there must be a way to do this all in one go from the modal view controller.


I just played around with this. I ended up with this:

  1. Pass the (original) view controller to the modal view controller via a property. The next view controller (that will need to be pushed) could also be passed as a property (if it's not always the same).
  2. Present the modal view.
  3. In the modal view controller method that dismisses the modal view, also push the next view controller by accessing the navigation controller from the original view controller property.

You end up with the sliding down and sliding right animations happening at the same time, but I think it looks ok.

Code:
In the original view controller:

- (IBAction)pushModalVC {
    ModalViewController *modalVC = [[ModalViewController alloc] init];

    modalVC.ownerVC = self;

    [self presentModalViewController:modalVC animated:YES];

    [modalVC release];
}

In the modal view controller:

- (IBAction)pushSecondVC {
    // this could be accessed via a property rather than loading
    SecondViewController *secondVC = [[SecondViewController alloc] init];

    [self dismissModalViewControllerAnimated:YES];

    [ownerVC.navigationController pushViewController:secondVC animated:YES];

    [secondVC release];
}


I've answered something similar to this earlier on (see question) with the same solution as you're currently using (see point 2 of my answer) but I thought of something like handling the flag not as a boolean, but to do it using an enum, so 1 variable will be enough.

typedef enum {
    ViewControllerPushControllerNone,
    ViewControllerPushControllerSettings,
    ViewControllerPushControllerWhatever
} ViewControllerPushController;

@interface ViewController : UIViewController {
    ViewControllerPushController _pushController;
}
@property(nonatomic, assign) ViewControllerPushController pushController;

@end




@implementation ViewController

@synthesize pushController = _pushController;

- (void)viewDidAppear:(BOOL)animated {
    switch(self.pushController){
        case ViewControllerPushControllerSettings:
            // Push Settings controller
        break;
        case ViewControllerPushControllerWhatever:
            // Push Whatever controller
        break;
    }
    self.pushController = ViewControllerPushControllerNone;

    [super viewDidAppear:animated];
}

@end

I think it's the best way you can get. This way, you keep the pushing of a controller in the main navigation controller, which is a good thing, and it's easy to manage I think.

EDIT You could also set the property to be a class, so you don't have to mess with the enum typedef. You could then also omit the switch statement, because you can then do something like:

- (void)viewDidAppear:(BOOL)animted {
    if(self.pushController != nil){
        NSString *selector = [NSString stringWithFormat:@"push%@", NSStringFromClass(self.pushController)];
        [self performSelector:NSSelectorFromString(selector)];
    }
    self.pushController = nil;

    [super viewDidAppear:animated];
}

- (void)pushSettingsViewController {
    if(_settingsViewController == nil){
        _settingsViewController = [[SettingsViewController alloc] init];
    }

    [self.navigationController pushViewController:_settingsViewController animated:YES];
}


The trick appears to be to not animate the first transition.

[self.navigationController dismissModalViewControllerAnimated:NO];
[self.navigationController pushViewController:controller animated:YES];  

Works.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜