During my last projects I have being using some techniques to create an alternative landscape view when developing my oriented UIViewController subclasses, such as AutosizingMask properties and adding additional code into some layoutSubviews methods. But now, I would like to allow my company's designer to work with the current project art just by editing some XIB files, and to do that I think I would need two viewControllers linked with their XIB file for each application oriented view.
So, I did start reading the View Controller Programming Guide for iOS document: http://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html#//apple_ref/doc/uid/TP40007457-CH101-SW26 and looked at this Apple sample code AlternateViews: http://developer.apple.com/library/ios/#samplecode/AlternateViews/Introduction/Intro.html
Although reading those documents, I could not create a oriented view that fits all my needs. Supposing I would like to create an oriented loading view just with a background image, a status label and an activity indicator. I would create:
MyLoadingView*Base*ViewController - Which is a base class that keeps logic and it's IBOutlets by being the fileOwner of next XIBs.
MyLoadingView*Portrait*ViewController - Which inherits the MyLoadingViewBaseViewController above and have a personalized portrait view into a MyLoadingViewPortraitViewController.xib
MyLoadingView*Landscape*ViewController - Which also inherits the MyLoadingViewBaseViewController and have a personalized landscape view into a MyLoadingViewLandscapeViewController.xib.
What I have learned indicates that a portrait class must contain a property which keeps an instance of the landscape class.
@interface MyLoadingViewPortraitViewController : MyLoadingViewBaseViewController {
BOOL _isShowingLandscapeView;
MyLoadingViewLandscapeViewController *_landscapeViewController;
} @end
And when the device is rotated, the portrait view instance must present the landscape view instance over it has a modal view:
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
!_isShowingLandscapeView)
{
[self presentModalViewController:self.landscapeViewController
animated:NO];
_isShowingLandscapeView = YES;
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation) &&
_isShowingLandscapeView)
{
[self dismissModalViewControllerAnimated:NO];
_isShowingLandscapeView = NO;
}
}
That works, but let's talk about some Issues:
The default iPad rotation animation does not appear, the views swap suddenly resulting in an undesired experience to the user. When trying to fix it I found into the AlternateViews sample code the lines bellow.
- (void)orientationChanged:(NSNotification *)notification { // We must add a delay here, otherwise we'll swap in the new view // too quickly and we'll get an animation glitch [self performSelector:@selector(updateLandscapeView) withObject:nil afterDelay:0]; }
But the final rotation animation with it also does not appear like a default rotation of a view using autosizingMasks.
I am not comfortable about using a modal view presentation. Think about trying to rotate a view that is current defined as the detailed view controller into a UISplitViewController. If the detailed view implements this code, after a device rotation it would appear over the split view. (Maybe adding as a subview can be a different solution. Did some of you tried it?)
Why not use the UIViewController "Responding to View Rotation Events" methods instead of listening for UIDeviceOrientationDidChangeNotification. (When the landscape view 开发者_Go百科is the frontmost view over the window, it will receive those rotate event methods and can resend to the portrait view which will continue managing it.)
Finally, I would appreciate for any answers, tips or sample codes for being creating a oriented view. Thanks in advance.
精彩评论