Modal View Controller Won't Start in Landscape Mode
I have a navigation based app that has a detail view (UIWebView) with action buttons across the bottom in a UIToolbar. I want to add 'notes' when the 'notes' button is开发者_如何学编程 pushed. Everything works fine when the webview is in portrait mode. I press the notes button, the modal view opens fine and works great.
The problem occurs when the webview is in landscape mode. If I press the notes button, all the code to open the modal view gets called but all I get is a white screen. One comment: If I open the modal view in portrait and then rotate the device, it rotates fine into landscape mode. It just won't open correctly in landscape mode.
I have another button that brings up the mail composer which has the identical behavior. Here is the code in my UIWebViewController:
- (IBAction)addNotes:(id)sender
{
NotesViewController *notesViewController;
// create the view controller and set it as the root view of a new navigation
// controller
notesViewController = [[NotesViewController alloc] initWithPrimaryKey:self.record.primaryKey];
UINavigationController *newNavigationController =
[[UINavigationController alloc] initWithRootViewController:notesViewController];
// present the navigation controller modally
[self presentModalViewController:newNavigationController animated:YES];
[notesViewController release];
[self.view setNeedsDisplay]; // not sure if I need this! I was trying different things...
[self.devotionText setNeedsDisplay]; // ditto...
[newNavigationController release];
}
Any ideas? I've tried all sorts of different things to no avail. I just get a white screen with no navigation bar (although there is a status bar at the top).
Modals don't always get information about rotations, and they get their info from the status bar, which doesn't always work right. Put this in your viewWillAppear to fix: [UIApplication sharedApplication].statusBarOrientation = self.interfaceOrientation
And, if you want a navigation controller inside your modal, you need to create one.
Also, you don't need the setNeedsDisplay. That only effects the current views, not the modal you are presenting.
Answer is here:
https://stackoverflow.com/a/10250747/1449618
Use the window's root view controller to present:
[self.view.window.rootViewController presentViewController:masterView
animated:YES
completion:NULL];
Wow, I lost days over that issue ... but I found a solution!
I had the same problem you had: the method "presentModalViewController:animated:" only worked in portrait mode.
After a lot of trial and error, I found out that the reason was that I had several view controllers active at the same time. I implemented a navigation system which switched between different view controllers, with one parent handling the children. (I could not use UINavigationController, because I needed a different look.)
So, my root view controller had a root view object, and several child view controllers. When a child view controller was activated, its view object was added as subview to the view of the root view controller.
The "presentModalViewController" method didn't like that. However, as soon as I set the "parentViewController" property of the child view controllers, it worked!
The problem is only that "parentViewController" is a read-only property. You have to extend the UIViewController class so you can access it.
@interface UIViewController (HelperExtension)
@property (nonatomic, assign) UIViewController *parent;
@end
@implementation UIViewController (HelperExtension)
- (UIViewController *)parent
{
return self.parentViewController;
}
- (void)setParent:(UIViewController *)parent
{
[self setValue:parent forKey:@"_parentViewController"];
}
@end
So, whenever you add the view of a child view controller to your parent view controller, call the "setParent:" method after doing it. Then it will work!
Got the same issue when presenting modally a navigation controller. Be sure to have correctly implement : shouldAutorotateToInterfaceOrientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
BOOL shouldAutorotate = NO;
if( isControllerMangingAllOrientations )
{
shouldAutorotate = YES;
}
else
{
shouldAutorotate = (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
return shouldAutorotate;
}
I was setting the boolean in the viewDidLoad method, not a good idea. Putting it in the initWithNibName:bundle: method is the right place.
If you use presentModalViewController just for animation like me, you can use pushViewController with animation as below answer;
Showing pushviewcontroller animation look like presentModalViewController
and you can close the viewController as below;
CATransition* transition = [CATransition animation];
transition.duration = 0.3;
transition.type = kCATransitionFade;
transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController popViewControllerAnimated:NO];
Hope it helps..
I had the task to show a video player in landscape mode.
AVPlayerViewController *playerViewController = [AVPlayerViewController new];
//Player init code goes here....
// #define degreesToRadian(x) (M_PI * (x) / 180.0) - was defined previously in a class header
playerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
playerViewController.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
playerViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self presentViewController:playerViewController animated:YES completion:nil];
You don't need a new Navigation Controller.
- (IBAction)addNotes:(id)sender {
NotesViewController *notesViewController;
// create the view controller and set it as the root view of a new navigation
// controller
notesViewController = [[NotesViewController alloc] initWithPrimaryKey:self.record.primaryKey];
[self.navigationController pushViewController: notesViewController animated: YES];
[notesViewController release];
}
精彩评论