6

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).

D-eptdeveloper
  • 2,430
  • 1
  • 16
  • 30
Glasswing
  • 61
  • 1
  • 3

7 Answers7

7

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.

MishieMoo
  • 6,620
  • 2
  • 25
  • 35
  • Thanks for replying so quickly! I tried putting the statusBarOrientation code into my NotesViewController viewWillAppear and I still get the same behavior! I also removed the new navigation controller and still don't get anything...just the white screen. Any other suggestions? – Glasswing Sep 22 '10 at 18:05
  • Can you post some code for the initWithPrimaryKey function? Posting some code on that file will help immensely! – MishieMoo Sep 22 '10 at 18:18
  • The init function is simple...the xib file is just a UIView with a UITextView under it. – Glasswing Sep 22 '10 at 18:29
  • Actually the nib is just a UIView and I create the UITextView programmatically. (I've tried it both ways...) – Glasswing Sep 22 '10 at 18:45
  • Have you tried logging your subviews? Add in a NSLog in viewWillAppear that prints out the subviews (self.view.subviews) to make sure your textfields are actually getting created. Are they? Have you stepped through this in the debugger? – MishieMoo Sep 23 '10 at 14:07
  • Yep. The textview is getting created. I have set the background view to blue and the textview to red (to debug). I even commented out creating of the textview subview. When I open the notes view (the blue one) in landscape, it still shows a white screen (not blue). I'm thinking that maybe it has to do with frames/layouts/layers? I'm completely stumped... – Glasswing Sep 24 '10 at 15:26
4

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];
Community
  • 1
  • 1
Jimmy_m
  • 1,568
  • 20
  • 24
2

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!

PrimaryFeather
  • 479
  • 3
  • 12
  • This also worked for me. You weren't using BCTabBarController by any change, were you? So much trouble for those little animating arrows... – Craig McMahon Dec 02 '11 at 02:37
2

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.

ıɾuǝʞ
  • 2,829
  • 26
  • 38
  • fighting with this exact issue and forgot that by default XCode 4 is adding: `- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ return (interfaceOrientation == UIInterfaceOrientationPortrait); }` No wonder it was always portrait.... *sigh* – Josh Peak Jun 29 '12 at 00:40
0

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..

Community
  • 1
  • 1
seymatanoglu
  • 151
  • 1
  • 9
0

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];
David
  • 1,061
  • 11
  • 18
-1

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];
}
Stephen Furlani
  • 6,794
  • 4
  • 31
  • 60
  • I removed the navigation controller and am still getting the same behavior. Thanks so much for replying. Any other ideas? – Glasswing Sep 22 '10 at 18:05