jmasterx
jmasterx

Reputation: 54123

Presenting a new view controller without infinitely stacking them?

I am working on an app where it is kind of like a website. There is a menu that every viewcontroller has in it and that needs to switch to the correct view.

There is no concept of back in my application. Thus, if I use UINavigation to push a view, I end up stacking up lots of views.

Same problem if I add the vc as a child or present it, you end up with hundreds of vcs after a while.

What is a way I can design this to safely have only 1 view at any given time?

Thanks

Upvotes: 1

Views: 189

Answers (3)

Neru
Neru

Reputation: 676

You can also sublass your UINavigationController class and override pushViewController:animated: method as follow:

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {

    if (self.viewControllers.count > <#the number of controllers you want to keep in memory eg. 20 #>) {
        NSMutableArray *mutableViewControllers = [self.viewControllers mutableCopy];
        //remove 2 last controllers in controller stack (from the bottom)
        [mutableViewControllers removeObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)]];
        self.viewControllers = [mutableViewControllers copy];
    }

    [super pushViewController:viewController animated:animated];
}

This approach gurantees you to alloc init controllers in normal way and don't bother about they pointers to memory.

Upvotes: 0

Eyeball
Eyeball

Reputation: 3317

Like this.

Add this to all your controllers that have access to the navigation controller. When you want to push a new controller, instead of using pushViewController:animated you can use this. You can modify the code to take animated as a parameter aswell.

- (void)pushIfNotInStack:(UIViewController*)viewController
{
    BOOL isInStack = NO;
    NSMutableArray * vcStack = [self.navigationController.viewControllers mutableCopy];
    for (NSInteger i = 1 ; i <vcStack.count; i++){
        if ([viewController isKindOfClass:[[vcStack objectAtIndex:i]class]]) {
            [vcStack replaceObjectAtIndex:i withObject:viewController];
            isInStack = YES;
        }
    }

    if(isInStack){
        [self.navigationController setViewControllers:vcStack];
        [self.navigationController popToViewController:viewController animated:YES];
    } else {
        [self.navigationController pushViewController:viewController animated:YES];
    }
}

Upvotes: 1

ukim
ukim

Reputation: 2465

Use a tab bar view controller and hide the tab bar.

A tab view controller can have a number of children view controllers. You can add these children view controllers in storyboard or in code.

enter image description here

You can use your menu to choose which child view controller you want to display. The children view controllers are indexed from 0 to n - 1, where n is the number of view controllers. If you want to display the view controller at index i:

[self.tabBarController setSelectedIndex:i];

Don't forget to hide your tab bar in each child view controller's viewDidLoad

Upvotes: 0

Related Questions