Question

I am trying to create a View that has a container in it. On that View, I want to switch between a table view and a map view. Yelp's app does exactly what I'm looking to do.

The problem I'm running into is switching between the views. Here is how my storyboard is set up:

Storyboard

I created a controller that is used to switch between the table and the map. The problem is if I use a modal or custom segue, it takes over the whole view.

I've tried embedding them in a navigation controller which does work (I think), but then once the user clicks on something in the controller I need to take them out of that navigation controller and back into the main navigation.

Was it helpful?

Solution

One way to do this, is to make the SwitchViewController a custom container controller, and add either the table view or map view as its child. Here is an example that I've used before that has the same set up as your storyboard (my ContainerViewController is your SwitchViewController, and my controllers with the identifiers "InitialVC" and "substituteVC" would be your table view and map view). This is code I have in the ContainerViewController,

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UIViewController *initial = [self.storyboard instantiateViewControllerWithIdentifier:@"InitialVC"];
    [self addChildViewController:initial];
    [self.view addSubview:initial.view];
    self.currentController = initial;
    [self constrainViewEqual:self.currentController];
}

-(void)switchToNewView {
    UIViewController *sub = [self.storyboard instantiateViewControllerWithIdentifier:@"SubstituteVC"];
    [self addChildViewController:sub];
    sub.view.frame = self.view.bounds;
    [self moveToNewController:sub];
}

-(void)moveToNewController:(UIViewController *) newController {
    [self.currentController willMoveToParentViewController:nil];
    [self transitionFromViewController:self.currentController toViewController:newController duration:.6 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{}
         completion:^(BOOL finished) {
             [self.currentController removeFromParentViewController];
             [newController didMoveToParentViewController:self];
             self.currentController = newController;
             [self constrainViewEqual:self.currentController];
         }];
}

constrainViewEqual is a category method that I use to set up the layout constraints for the views. It looks like this,

-(void)constrainViewEqual:(UIViewController *) vc {
    [vc.view setTranslatesAutoresizingMaskIntoConstraints:NO];
    NSLayoutConstraint *con1 = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeCenterX relatedBy:0 toItem:vc.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
    NSLayoutConstraint *con2 = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeCenterY relatedBy:0 toItem:vc.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
    NSLayoutConstraint *con3 = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeWidth relatedBy:0 toItem:vc.view attribute:NSLayoutAttributeWidth multiplier:1 constant:0];
    NSLayoutConstraint *con4 = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeHeight relatedBy:0 toItem:vc.view attribute:NSLayoutAttributeHeight multiplier:1 constant:0];
    NSArray *constraints = @[con1,con2,con3,con4];
    [self.view addConstraints:constraints];
}

I call switchToNewView from a button in the initial view controller (the one you have labeled as ViewController) like this,

-(IBAction)doStuff:(id)sender {
    ContainerController *cc = (ContainerController *)self.childViewControllers[0];
    [cc switchToNewView];
}

OTHER TIPS

You can add the new detail viewControllers to the storyboard and configure the size of them to match the container from the interface builder

In utilities choose size - Freeform

then

In here you can specify the dimensions

Segue from your switch view controller and the new view controller should only take up the size of that view.

I hope this helps,

Cheers,

Jim

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top