Question

My iPad app makes heavy use of autorotation. This is great. However, I've noticed that if a hidden view is released by the default implementation of didReceiveMemoryWarning (as described here), when the view is re-loaded from the nib and I happen to be in landscape, it loads it in portrait. This wreaks havoc with the interface until I rotate the iPad manually and force it to go to the proper orientation.

I had assumed that iOS would load the view in the current orientation; that's what it does when the app launches. But it no, not after being unloaded by didReceiveMemoryWarning. Why not? And how can I get it to do that?

Was it helpful?

Solution

The answer, determined thanks to pointers from dbarker, is that the view controller's rotation methods, including -willRotateToInterfaceOrientation:duration: and -willAnimateRotationToInterfaceOrientation:duration:, will not be called when a view is reloaded after a the default implementation of didReceiveMemoryWarning has unloaded the view. I've no idea why it would be different on app launch, but I do have a workaround

What I did was to set a boolean ivar, named unloadedByMemoryWarning, to YES in didReceiveMemoryWarning, like so:

- (void) didReceiveMemoryWarning {
    unloadedByMemoryWarning = YES;
    [super didReceiveMemoryWarning];
}

Then, in viewDidLoad, if that flag is true, I set it to NO and then call the rotation methods myself:

if (unloadedByMemoryWarning) {
    unloadedByMemoryWarning = NO;
    [self willRotateToInterfaceOrientation:self.interfaceOrientation duration:0];
    [self willAnimateRotationToInterfaceOrientation:self.interfaceOrientation duration:0];
    [self didRotateFromInterfaceOrientation:self.interfaceOrientation];
}

Kinda sucks that I have to do this, but it does work, and now I'm less concerned about getting killed by iOS for using too much memory.

OTHER TIPS

  1. I think iOS 5 might fix this.

  2. For iOS 4.3, I've had good luck with another fix. After the load from nib:

    [parent.view addSubview:nibView];  
    nibView.frame = parent.view.frame;  
    [nibView setNeedsLayout];  
    

    If that worked, you could jettison the unloadedByMemoryWarning logic, since it's safe to do every load. Got the tip & code (basically) from here.

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