Harshal Wani
Harshal Wani

Reputation: 2349

ObjectiveC: Add/Perform multiple segue in navigation controller

I'm implementing an application feature where it has 6-7 screens inflow. And user can left/close flow at any screen.

But when the user again applies for an application, they should jump to the last screen where he left and also he can able to go back to previous screens.

For e.g: I started to apply for application and completed till 4th screen and close. Again apply, I must jump directly to the 4th screen and also able to go back to 3rd->2nd->1st screen from the stack.

Current Code:

Segue identifires for screens from 1-7 in Storyboard are "screen1", "screen1" ... "screen7"

From HomeScreen.m

-(void)toPersonalApplication {

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Personal" bundle:nil];
    ScreenOne *screenOne = [storyboard instantiateViewControllerWithIdentifier:@"screenOne"];
    UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:screenOne];
    [self presentViewController:nav animated:YES completion:nil];
}

Checking if the user has already started an application process:

On ScreenOne.m

   - (IBAction)btnNextClick:(id)sender {

        if (doneProcessTill == 4) {

        // Should be execute something like this here
        // [self performSegueWithIdentifier:@"screen2" sender:self];
        // [self performSegueWithIdentifier:@"screen3" sender:self];
        // [self performSegueWithIdentifier:@"screen4" sender:self];
      }

    }

Appreciate your suggestion! Thanks

Upvotes: 0

Views: 45

Answers (2)

Matic Oblak
Matic Oblak

Reputation: 16794

For this case it would be best to save your view controllers and then show them again once you want to go back to where you were. At any point you can get what are the current view controllers using navigationController.viewControllers. And to set the whole stack all you need to do is call setViewControllers on your navigation controller.

You could override a navigation controller to store the array of controllers. Or you can just save it statically. Whichever is more convenient in your case.

The static one would look something like this:

static NSArray<UIViewController *> *__preservedControllers = nil;

@implementation ViewController

- (void)onClose {
    __preservedControllers = self.navigationController.viewControllers;
    // Insert logic to close the whole procedure
}

- (void)reopenSavedStack {
    if(__preservedControllers) {
        [self.navigationController setViewControllers:__preservedControllers animated:YES];
        __preservedControllers = nil;
    }
}

With subclassing navigation controller it might look much nicer though:

@interface MyNavigationController : UINavigationController

@property (nonatomic, strong) NSArray<UIViewController *> *savedStack;

@end

@implementation MyNavigationController

- (void)saveStack {
    self.savedStack = self.viewControllers;
}

- (void)restoreStack:(BOOL)animated {
    if(self.savedStack.count > 0) {
        [self setViewControllers:self.savedStack animated:YES];
        self.savedStack = nil;
    }
}

@end

But you do need to typecast then:

- (void)onClose {
    [(MyNavigationController *)self.navigationController saveStack];
    // Insert logic to close the whole procedure
}

- (void)reopenSavedStack {
    [(MyNavigationController *)self.navigationController restoreStack:YES];
}

Upvotes: 0

Andr&#233; Slotta
Andr&#233; Slotta

Reputation: 14040

As stated in my comment a solution could look like this:

- (void)toPersonalApplication {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Personal" bundle:nil];

    NSMutableArray *viewControllers = [NSMutableArray array];
    for (NSInteger i = 1; i <= doneProcessTill; ++i) {
        UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:[NSString stringWithFormat:@"screen%ld", (long)i]];
        [viewControllers addObject:viewController];
    }

    UINavigationController *navigationController = [UINavigationController new];
    navigationController.viewControllers = viewControllers;

    [self presentViewController:navigationController animated:YES completion:nil];
}

Upvotes: 1

Related Questions