Ryan Ryan - 2 months ago 10x
iOS Question

How to pop back to root view controller but then push to a different view?

I am writing a simple application that has 3 view controllers. The root view controller is an

item listing
, basic table view. Off of this view controller, I push two different view controllers based on some user interaction - a
create item
view controller or a
view item
view controller.

So, the storyboard segues just look like a V, or something.

On my
create item
view controller, I would like it to pop back to the root view controller when the user creates a new item, but then push to the
view item
controller so that I can look at the newly created item.

I can't seem to get this to work. It's easy enough to pop back to the root view controller, but I'm unable to push that
view item

Any ideas? I've pasted my code, below. The pop function works, but the new view never appears.

- (void) onSave:(id)sender {

CLLocation *currentLocation = [[LocationHelper sharedInstance] currentLocation];

// format the thread object dictionary
NSArray* location = @[ @(currentLocation.coordinate.latitude), @(currentLocation.coordinate.longitude) ];
NSDictionary* thread = @{ @"title": _titleField.text, @"text": _textField.text, @"author": @"mustached-bear", @"location": location };

// send the new thread to the api server
[[DerpHipsterAPIClient sharedClient] postPath:@"/api/thread"
success:^(AFHTTPRequestOperation *operation, id responseObject) {

// init thread object
Thread *thread = [[Thread alloc] initWithDictionary:responseObject];

// init view thread controller
ThreadViewController *viewThreadController = [[ThreadViewController alloc] init];
viewThreadController.thread = thread;

[self.navigationController popToRootViewControllerAnimated:NO];
[self.navigationController pushViewController:viewThreadController animated:YES];

failure:^(AFHTTPRequestOperation *operation, NSError *error) {

[self.navigationController popToRootViewControllerAnimated:YES];




An easy way to accomplish what you want to do is to build some simple logic into your main root view controllers -(void)viewWillAppear method and use a delegate callback to flip the logic switch. basically a "back reference" to the root controller. here is a quick example.

main root controller (consider this controller a) - well call it controllerA set a property to keep track of the jump status

@property (nonatomic) BOOL jumpNeeded;

setup some logic in

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.jumpNeeded ? NSLog(@"jump needed") : NSLog(@"no jump needed");

    if (self.jumpNeeded) {
        self.jumpNeeded = NO;
        [self performSegueWithIdentifier:@"controllerC" sender:self];

Now, in your main root controller,when a tableview row is selected do something like this when pushing to controllerB in your tableView did select method

[self performSegueWithIdentifer@"controllerB" sender:self];

then implement your prepare for segue method

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

  //setup controller B
  if([segue.identifier isEqualTo:@"controllerB"]){
    ControllerB *b = segue.destinationViewController;
    b.delegate = self;  //note this is the back reference

  //implement controller c here if needed

Now move on to controllerB you need to set a property called "delegate" to hold the back reference and you need to import the header file from the root controller

#import "controllerA"

@property (nonatomic,weak) controllerA *delegate;

then just before you pop back to controllerA, you set the flag

   self.delegate.jumpNeeded = YES;
    [self.navigationController popViewControllerAnimated:YES];

and that is about it. You don't have to do anything with controllerC. There are a few other ways to do, but this is pretty straight forward for your needs. hope it works out for you.