xcodeiPhone OS 3.0 beta 3 has been available for a few weeks and it’s actually pretty stable. The most annoying bug in the standard functionality must be that quite often the last row of buttons in phone mode disappear. A reboot fix that until next time it happens, but it’s annoying.

Unfortunately I haven’t had the time to mess around much with the new APIs in 3.0. I’ve tested my Hitta Hem application and found a breaking change to the shouldAutorotateToInterfaceOrientation which I use to rotate images in an UIScrollView. I’ve explained and posted that code. Since beta 1 of iPhone OS 3.0 shouldAutorotateToInterfaceOrientation doesn’t behave like in 2.x, which is a problem. In 2.x that event always fire, regardless, when you rotate the device. In 3.0 beta however, if you return false (don’t rotate) when you turn the divide to landscape, the even won’t fire again when the device is rotated back to UIInterfaceOrientationPortrait. If you return true when it was rotated to landscape, it will fire when it’s rotated back to UIInterfaceOrientationPortrait. The problem is of course that if you return true, the entire UI will rotate, and I don’t want to support the entire application in landscape. This is probably some kind of “optimization”, but I can’t imagine it’s a huge CPU saver to prevent one event from firing.

I’ve also found another bug/change that relate to this. If you inherit a UIViewController and retrieve the interface orientation using self.interfaceOrientation it will fire the shouldAutorotateToInterfaceOrientation event, so if you were to use that method inside the event reciever for shouldAutorotateToInterfaceOrientation, you’ll get an infinite loop.

Hopefully Apple will change this back to how it works in 2.x. I have sent in a bug report covering both these issues but haven’t got any replies on it. Of course the rotation can be solved using the accelerometer, I’ve already looked into it, and if there are no changes in the next beta I will try to post an updated solution.

*UPDATE*

Kyle posted a response to another post I made about determining the interface orientation using the accelerometer. It’s possible to listen to the UIDeviceOrientationDidChangeNotification event by attaching to NSNotificationCenter and get exactly the same fuctionality in 3.0 as in previous versions.

Attach to the event, this can be done at viewDidLoad, viewWillAppear etc:

-(void) viewWillAppear: (BOOL) animated{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(receivedRotate:) name: UIDeviceOrientationDidChangeNotification object: nil];
}

Recieve the event:

-(void) receivedRotate: (NSNotification*) notification
{
   UIDeviceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
   if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
   {
 
   }
}

Unregister from the event, this should be done when you don’t need the event anymore for example in viewWillDisappear:

-(void) viewWillDisappear: (BOOL) animated{
[[NSNotificationCenter defaultCenter] removeObserver: self];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}

Big thanks to Kyle for this code!

I’ve updated my original example with this code for iPhone OS 3.0. Check it out!

Related posts