Bill
Bill

Reputation: 45408

Modal view controller size with master-detail controller

My app has a split master-detail interface: when the user hits a particular button in the detail side of the screen, I use a UIModalTransitionStyleFlipHorizontal modalTransitionStyle so that I can just present a new controller modally and have it appear as if the details panel has "flipped" to the new interface.

While this works fine on the iPhone, when I try it on the iPad, the new modal controller flips from the details side of the screen but at the end of the animation, it's covering the entire screen.

How can I cause the controller to flip only within the details side of the screen?

Upvotes: 3

Views: 2271

Answers (3)

Daniel
Daniel

Reputation: 23359

For me there are 2 options, a correct way (view animation transitions) and a hacky way (get dirty with modally presenting a controller).

First the hacky way, you could present your modal view controller, as you know, a modal view controller takes over the screen and is the only accessible controller whilst presented, but you could resize it so it ends up to present above the detail section of the screen only, the problem here is that it's not intended to be resized and misplaces and also it's really easy to run into problems when rotations occur. Also you won't be able to interact with the master part of your UISplitViewController while this controller is present.

This could be done like this for example:

UIViewController *detail = [[UIViewController alloc] init];

detail.modalPresentationStyle = UIModalPresentationFormSheet;
detail.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;

if([self respondsToSelector:@selector(presentViewController:animated:completion:)]){
    [self presentViewController:detail animated:YES completion:nil];
}else{
    [self presentModalViewController:detail animated:YES];
}

detail.view.superview.frame = CGRectMake(320.0, 0.0, self.view.frame.size.width - 320.0, self.view.frame.size.height);

[detail release];

You may need to adjust the centre of detail view controllers view's superview... This I don't recommend.

Your other solution is to use UIView animations inside your detail view controller to swap your view and animate to flip round.

To see how that would look, check out the Facebook app for iOS, in the chat when you're in a conversation you can tap the [...] button on top right and the view's contents flip around and you can adjust the notification settings for that person/chat.

For example you could do the following when you tap a button in the detail view controller:

UIViewController *someOtherController = [...];

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.8];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
                       forView:self.view
                         cache:YES]; 

[self.view addSubview:someOtherController.view];

[UIView commitAnimations];

You would do the reverse to remove it.

Upvotes: 0

CocoaEv
CocoaEv

Reputation: 2984

if you haven't figured this out yet, you are most of the way there. You need to define the presentation context of the modal view for "current context" so that it only operates in the detail view and not on the entire superview.

the simplest way to do this is to setup the view in storyboard with a segue. In IB, create the new view controller, add a segue and edit the segue line by giving it a name "flipper", set it to modal, set it to flip and set it's presentation to "current context".

Once those properties are set, you can just segue to the view controller - but initiate it from the detail view controller like this:

[self performSegueWithIdentifier:@"flipper" sender:self];

If you need to do the transition in code it would look something like this:

UIViewController *abc = [self.storyboard instantiateViewControllerWithIdentifier:@"flipper"];
[abc setModalPresentationStyle:UIModalPresentationCurrentContext];
[abc setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentViewController:abc animated:YES completion:nil];

be well.

Upvotes: 4

Bill
Bill

Reputation: 45408

My problem was that I was presenting the controller from a regular UIViewController, but I should have been presenting it from the split-view controller.

Upvotes: 0

Related Questions