سؤال

I have a UINavigationController with 4 items:

(root)mainvc -> callerlistvc -> addcallerformvc -> verifycallervc (in that specific order)

When I am on the verifycallervc screen, if I press back, I want to go back to callerlistvc.

Here is the catch however, the back button should be a system button.. So.. as far as I know I cannot replace the action with a selector calling poptoviewcontroller:animated (only works on a custom uibarbuttonitem)

So then I thought of manipulating the stack (pretty interesting and challenging too!) So here is what I did...

So currently Im on the verifycallervc screen... and this gets called.

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

NSMutableArray *allViewControllers = [self.navigationController.viewControllers mutableCopy];

__block UIViewController *mainvc = nil;
__block UIViewController *callerlistvc = nil;
__block UIViewController *addcallerformvc = nil;

[allViewControllers enumerateObjectsUsingBlock:^(UIViewController *vc, NSUInteger idx, BOOL *stop) {
    if ([vc isKindOfClass:[MainVC class]]) {
        mainvc = vc;
    } else if ([vc isKindOfClass:[CallerListVC class]]) {
        callerlistvc = vc;
    } else if ([vc isKindOfClass:[AddCallerFormVC class]]) {
        addcallerformvc = vc;
    }
}];

[self.navigationController setViewControllers:@[ mainvc, callerlistvc, self]];
}

After I did that, I pressed back normally and was now on the callerlistvc... great. Unfortunately when I press the button (push-segued to addcallerformvc)... it results in a crash EXC_BAD_ACCESS.

I also tried a different approach by first manipulating the variable callerlistvc like so before adding it in the setViewControllers method

callerlistvc = [[UIStoryboard storyboardWithName:@"main" bundle:nil] instantiateViewControllerWithIdentifier:@"CallerListVC"];

But the result is the same.

I have added breakpoints and it goes like this...

CallerListVC:

  1. tappedShowAddCallerListButton
  2. performSegueWithIdentifier
  3. prepareForSegue // identifier string is correct, destinationVC is not nil

then AddCallerFormVC: 4. viewDidLoad 5. viewWillAppear // properties not nil

after that EXC_BAD_ACCESS occurs

How can I make this work?

هل كانت مفيدة؟

المحلول

The better approach in this case would be to use a custom UINavigationController class and extend the popViewControllerAnimated: method. In this method either call the super method or pop to the specific view controller (super class method) based on a check. That way you have your system nav buttons and also control where the tack should pop to.

نصائح أخرى

Don't override anything in verifycallervc and instead do following with normal back on verifycallervc

Override viewWillAppear or viewDidAppear for addcallerformvc like this

- (void)viewDidAppear:(BOOL)animated
{
   if (![self isBeingPresented]) {
      [self.navigationController popViewControllerAnimated:YES];
   }
}

Reference : https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/RespondingtoDisplay-Notifications/RespondingtoDisplay-Notifications.html#//apple_ref/doc/uid/TP40007457-CH12-SW7

Note: not tested, don't have XCode right now....

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top