IOS record 11: Code iOS screen rotation

Lead: iOS App is the most pages only show the vertical screen under the effect, but a few pages need to support screen. This paper introduces the rotation direction of the monitor screen, the setting of the rotation direction of the view controller, the view processing in the direction of the screen rotation and the processing of the forced screen

First, monitor the screen rotation direction

In the iOS screen, and often UIDeviceOrientation, UIInterfaceOrientation and UIInterfaceOrientationMask of the three enumeration type deal, they describe the screen rotation direction from different angles.

1, UIDeviceOrientation: device direction

The direction of iOS equipment is obtained through the iOS accelerometer.

1) iOS defines the following seven device directions

Typedef NS_ENUM (NSInteger, UIDeviceOrientation) {/ / UIDeviceOrientationUnknown, unknown direction, may be the device (screen) oblique UIDeviceOrientationPortrait / equipment (screen) vertical UIDeviceOrientationPortraitUpsideDown / / equipment (screen) erect, upside down UIDeviceOrientationLandscapeLeft, / / equipment (screen) to the left transverse UIDeviceOrientationLandscapeRight / / equipment (screen) to tap UIDeviceOrientationFaceUp. / / equipment (screen) in flat UIDeviceOrientationFaceDown / equipment (screen) lying down};

Explanation: UIDeviceOrientation refers to the direction of the home key, such as: home direction in the right, device (screen) direction to the left (UIDeviceOrientationLandscapeLeft)

2) read device direction

The UIDevice single case represents the current device. Information can be obtained from this single instance device, such as device direction orientation.

UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;

3) monitor, process, and remove notifications of changes in device direction

When the device changes direction, UIDeviceOrientationDidChangeNotification notifications are sent; register to listen to the notifications and display views for different device directions.

/ / open and monitoring equipment rotating notice (not open, the direction of equipment has been UIInterfaceOrientationUnknown ([UIDevice) if! CurrentDevice].generatesDeviceOrientationNotifications) {[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]}; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector (handleDeviceOrientationChange:) name:UIDeviceOrientationDidChangeNotification object:nil]; / / processing equipment change direction - (void) handleDeviceOrientationChange: (NSNotification *) notification{UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation; switch (ddeviceOrientation UIDeviceOrientationFaceUp:) {case (@ NSLog" Flat screen up); break; case UIDeviceOrientationFaceDown: NSLog (@ "flat screen down"); break case; UIDeviceOrientationUnknown: NSLog (@ "unknown direction"); break case; UIDeviceOrientationLandscapeLeft: NSLog (@ "screen left transverse"); break case; UIDeviceOrientationLandscapeRight: NSLog (@ "screen right transverse") break; case; UIDeviceOrientationPortrait: NSLog (@ screen "upright"); break case; UIDeviceOrientationPortraitUpsideDown: NSLog (@ "screen erect, upside down"); break; default: NSLog (@ "B" is not recognized); Reak;}} / / in the end dealloc removes the notice and notice the equipment end rotation - (void) dealloc{[[NSNotificationCenter defaultCenter]removeObserver:self]; / /... [[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];}

Explanation: when the handset locks the vertical screen, the UIDeviceOrientationDidChangeNotification notification fails.

2, UIInterfaceOrientation: interface direction

The direction of the interface is the direction of the interface in the reaction iOS, which is consistent with the direction of the Home button.

1) iOS defines the following five interface directions

Typedef NS_ENUM (NSInteger, UIInterfaceOrientation) {UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown, UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait / unknown direction, / / UIInterfaceOrientationPortraitUpsideDown / / UIDeviceOrientationPortraitUpsideDown = vertical interface interface, erect, upside down UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight, UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft / interface to the left / right interface towards __TVOS_PROHIBITED};

Description: from the definition, the direction of the interface and the direction of the corresponding relationship, such as the vertical direction of the interface is the vertical direction of equipment: UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown

2) read the interface direction

UIInterfaceOrientation is related to the status bar, which is obtained by a single instance call statusBarOrientation of UIApplication

UIInterfaceOrientation interfaceOrientation = [[UIApplication, sharedApplication], statusBarOrientation];

3) monitor, process, and remove notifications of changes in direction of the interface

When the interface changes in the direction of time, UIApplicationWillChangeStatusBarOrientationNotification and UIApplicationDidChangeStatusBarOrientationNotification has issued a notice; monitor the two registration notice, according to the different direction of view display processing interface.

In order to monitor / / UIApplicationDidChangeStatusBarOrientationNotification notification for [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector (handleStatusBarOrientationChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; / / interface direction change - (void) handleStatusBarOrientationChange: (NSNotification *) notification{UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; switch (interfaceOrientation) {case UIInterfaceOrientationUnknown: NSLog (@ "unknown"); break case; UIInterfaceOrientationPortrait: NSLog (@ "upright"); break interface; Case UIInterfaceOrientationPortraitUpsideDown: NSLog (@ "interface erect, upside down"); break case; UIInterfaceOrientationLandscapeLeft: NSLog (@ "interface to the left"); break case; UIInterfaceOrientationLandscapeRight: NSLog (@ "interface to the right"); break; default: break;}} / / finally removed in dealloc notice - (void) dealloc{/ /... [[NSNotificationCenter defaultCenter]removeObserver:self]; [[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];}

Explanation: the UIApplicationWillChangeStatusBarOrientationNotification and UIApplicationDidChangeStatusBarOrientationNotification notifications failed after the handset locked the vertical screen.

3, UIInterfaceOrientationMask

UIInterfaceOrientationMask is the type defined in order to integrate multiple UIInterfaceOrientation, and is related to ViewController, a total of 7

1) the definition of UIInterfaceOrientationMask in iOS

Typedef NS_OPTIONS (NSUInteger, UIInterfaceOrientationMask) {UIInterfaceOrientationMaskPortrait (< = 1; < UIInterfaceOrientationPortrait), UIInterfaceOrientationMaskLandscapeLeft (< = 1; < UIInterfaceOrientationLandscapeLeft), UIInterfaceOrientationMaskLandscapeRight (< = 1; < UIInterfaceOrientationLandscapeRight), UIInterfaceOrientationMaskPortraitUpsideDown (< = 1; < UIInterfaceOrientationPortraitUpsideDown), UIInterfaceOrientationMaskLandscape (UIInterfaceOrientationMaskLandscapeLeft = UIInterfaceOrientationMaskLandscapeRight, UIInterfaceOrientationMaskAll = | (UIInterfaceOrientationMaskPortrait) UIInterfaceOrientationMaskLandscapeLeft UIInterfaceOrientationMaskLandscapeRight UIInterfaceOrie | | | NtationMaskPortraitUpsideDown = UIInterfaceOrientationMaskAllButUpsideDown (UIInterfaceOrientationMaskPortrait), UIInterfaceOrientationMaskLandscapeLeft UIInterfaceOrientationMaskLandscapeRight, | |)} __TVOS_PROHIBITED;

2) the use of UIInterfaceOrientationMask

In ViewController, you can override the (UIInterfaceOrientationMask) supportedInterfaceOrientations method to return the type to determine which interface directions UIViewController can support.

/ / support interface (UIInterfaceOrientationMask) - supportedInterfaceOrientations{return vertical UIInterfaceOrientationMaskPortrait;}

Summary: UIDeviceOrientation (device orientation) and UIInterfaceOrientation (screen orientation) are two different concepts. The former represents a state of the device, which is the response of the screen to the user interface in order to respond to different device states. The iOS device rotates by UIKit received rotating events, and then notify the current program through the AppDelegate UIWindow object, UIWindow object to inform it of rootViewController, if the rootViewController support screen rotation direction, after the completion of the rotation or rotation; the popup ViewController is treated as such.

Two 、 the setting of rotation direction in view controller

0, on the prohibition of cross screen operations (not recommended)

There are two conventional methods.

Method 1: in the General–&gt of the project, Deployment Info–> Device Orientation, only Portrait (vertical screen) is checked

IOS record 11: Code iOS screen rotation
tick Portrait.png

Method 2:Device Orientation defaults, Appdelegate is implemented in supportedInterfaceOrientationsForWindow: and only UIInterfaceOrientationMaskPortraitt (vertical screen) is returned

- - (NSUInteger) application: (UIApplication *) application supportedInterfaceOrientationsForWindow: (UIWindow *) window {return UIInterfaceOrientationMaskPortrait}

Explanation: few APP interfaces are vertical because there is always an interface to support a horizontal screen, such as a video playback page. Therefore, it is not recommended to set the APP page horizontal screen prohibited.

The following describes how to make the rotation direction settings in the view controller in your project

1, APP supports multiple directions
IOS record 11: Code iOS screen rotation
APP supports multiple directions of.Png

Explanation: APP supports horizontal and vertical screens, but the page orientation of the specific view controller needs further processing. Since the Upside Down is not supported, even if the device is upside down, the device will not be turned upside down by API.

2, support ViewController screen orientation settings

1) critical functions

The interface direction supported by the view controller is mainly controlled by the following three functions

Whether / / automatic rotation, return YES can automatically rotate, return NO rotation (BOOL) shouldAutorotate ban NS_AVAILABLE_IOS __TVOS_PROHIBITED (6_0); / / return support direction - (UIInterfaceOrientationMask) supportedInterfaceOrientations NS_AVAILABLE_IOS __TVOS_PROHIBITED (6_0); / / screen orientation by the modal view controller introduced priority support - (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation NS_AVAILABLE_IOS (6_0) __TVOS_PROHIBITED;

2) QSBaseViewController settings

//QSBaseViewController.h @interface QSBaseController: UIViewController @end //QSBaseViewController.m @implementation QSBaseController //#pragma mark - control screen rotation method / whether automatic rotation, return YES can automatically rotate, return NO rotation (BOOL) shouldAutorotate{ban return NO;} / / return support direction - (UIInterfaceOrientationMask) supportedInterfaceOrientations{return UIInterfaceOrientationMaskPortrait;} / / screen orientation view controller by the launch of the first mode support - (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation{return UIInterfaceOrientationPortrait @end;}

1:QSBaseViewController the default does not support rotation, only support the interface in the vertical direction, the project Controller inherited from QSBaseViewController, this can be overridden through three methods to make Controller support in the direction of rotation or vertical screen outside.

3) in QSNavigationController settings

Object: when the push view controller is passed through the QSNavigationController, the settings that support the rotation of the screen are handed in to the latest push ([self.viewControllers lastObject]) viewController.

//QSNavigationController.h @interface QSNavigationController: UINavigationController @end //QSNavigationController.m @implementation QSNavigationController #pragma mark - control screen rotation method - (BOOL) shouldAutorotate{return self.viewControllers lastObject]shouldAutorotate] ";} - (UIInterfaceOrientationMask) supportedInterfaceOrientations{return [[self.viewControllers lastObject]supportedInterfaceOrientations];} - (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation{return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation] @end;}

4) in QSTabBarController settings

Objective: TabBarController is usually used as the whole program rootViewController, each Tab UITabBar shown above corresponds to a ViewController; each click of a Tab, the ViewController (self.selectedViewController) on screen rotation and support setting the direction to its own control.

//QSTabBarController.h @interface QSTabBarController: UITabBarController @end //QSTabBarController.m @implementation QSTabBarController #pragma mark - control screen rotation method - (BOOL) shouldAutorotate{return [self.selectedViewController shouldAutorotate];} - (UIInterfaceOrientationMask) supportedInterfaceOrientations{return [self.selectedViewController supportedInterfaceOrientations];} - (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation{return [self.selectedViewController preferredInterfaceOrientationForPresentation] @end;}

Three 、 view processing in the direction of the screen rotation

1, the screen rotation, it is recommended to listen to UIApplicationDidChangeStatusBarOrientationNotification

The reason that the 1:supportedInterfaceOrientations method ultimately returns multiple interface orientations.

Reason 2 (most important reason): what we really want to deal with is the rotation of the UI in the direction of the page. When the physical rotation of the device occurs, if the page of the current controller does not rotate at this point, we may change the UI layout at this point, and a problem may arise.

2 、 screen width and height

1) after iOS 8, the [[UIScreen mainScreen] bounds] changes as the screen rotates. The screen height is the screen height when the screen is vertical.

2) when we view layout, we don’t use SCREEN_HEIGHT and SCREEN_WIDTH directly, but use SCREEN_MIN and SCREEN_MAX if we use the width of the screen

#define SCREEN_HEIGHT CGRectGetHeight ([[UIScreen mainScreen] bounds]) #define SCREEN_WIDTH CGRectGetWidth ([[UIScreen mainScreen] bounds]) #define SCREEN_MIN MIN (SCREEN_HEIGHT, SCREEN_WIDTH) #define SCREEN_MAX MAX (SCREEN_HEIGHT, SCREEN_WIDTH)

Explanation: when the screen is vertical, the width is SCREEN_MIN, and the height is SCREEN_MAX. When the screen is horizontal, the width is SCREEN_MAX, and the height is SCREEN_MIN.

3, screen rotation processing Demo
/ / monitoring processing UIApplicationDidChangeStatusBarOrientationNotification - (void) handleStatusBarOrientationChange: (NSNotification *) notification{UIInterfaceOrientation interfaceOrientation sharedApplication] statusBarOrientation] BOOL = [[UIApplication; isLandscape = NO; switch (interfaceOrientation) {case UIInterfaceOrientationUnknown: NSLog (@ "unknown"); break case UIInterfaceOrientationPortrait:; case UIInterfaceOrientationPortraitUpsideDown: isLandscape = NO; break; case UIInterfaceOrientationLandscapeLeft: case UIInterfaceOrientationLandscapeRight: isLandscape = YES; break default:; Break (isLandscape);} if {self.tableView.frame = CGRectMake (0, 0, SCREEN_MAX, SCREEN_MIN - 44);}else{self.tableView.frame = CGRectMake (0, 0, SCREEN_MIN, SCREEN_MAX - 64)}; [self.tableView reloadData];}

Explanation: of course you can also AutoLayout layout third party library processing such a good choice to use Masonry, storyBoard to the layout of the second.

4, the screen rotation processing Demo renderings
IOS record 11: Code iOS screen rotation
vertical screen effect.Png
IOS record 11: Code iOS screen rotation
horizontal screen under the effect of.Png
5, suggestions for screen rotation processing

1) before and after rotation, view displays the current position as much as possible

2) the response of the temporary interface operation during the rotation

3) there is tableview in the view, after rotation, force [tableview reloadData] to ensure that after the change in direction, the new row can be full of full screen.

Four, forced screen

Some pages in APP, such as video playback pages, require a horizontal screen as soon as they appear. These horizontal screen pages or modal pop-up or push come in.

1, mode pop-up ViewController case forced screen settings
//QSShow3Controller.m - (BOOL) shouldAutorotate{return NO;} - (UIInterfaceOrientationMask) supportedInterfaceOrientations{return UIInterfaceOrientationMaskLandscapeRight;} - (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation{return UIInterfaceOrientationLandscapeRight;} / / *vc = [[QSShow3Controller alloc]init] QSShow3Controller popup mode; [self presentViewController:vc animated:YES completion:nil];

Explanation: This is a relatively simple procedure.

2, push push ViewController case, forced screen settings
//QSShow4Controller.m - (void) viewWillAppear: (BOOL) animated{[super viewWillAppear:animated]; [self setInterfaceOrientation:UIInterfaceOrientationLandscapeRight];} / / forced transfer screen (the best way to put in BaseVController) - (void) setInterfaceOrientation: (UIInterfaceOrientation) orientation{(if [[UIDevice currentDevice] respondsToSelector:@selector (setOrientation:)] SEL (NSSelectorFromString) {selector = @ "setOrientation:"); NSInvocation = *invocation [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:[UIDevice currentDevice]]; / / from the beginning of 2 because the first two parameters have been sele Ctor target and [invocation orientation atIndex:2] occupied setArgument:& [invocation; invoke];}} / / must return YES - (BOOL) shouldAutorotate{return YES;} - (UIInterfaceOrientationMask) supportedInterfaceOrientations{return UIInterfaceOrientationMaskLandscapeRight //Push QSShow4Controller *vc;} into = [[QSShow4Controller alloc]init]; [self.navigationController pushViewController:vc animated:YES];

Note that Apple does not allow a direct call to the setOrientation method, otherwise there is a risk of rejection; use the NSInvocation object to the [UIDevice currentDevice] message, forced to change equipment direction, the direction of the corresponding page change, this is apple allowed.

The above detailed source code reference: QSRotationScreenDemo