IPad screen adaptation

A switch, the monitor screen

In 1, notice:

UIApplicationDidChangeStatusBarFrameNotification [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector / / monitoring notification (changeRotate:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil]; (void) - changeRotate: (NSNotification*) noti deviceOrientation currentDevice] orientation] {UIDeviceOrientation = [[UIDevice; NSLog (@ "%d -", deviceOrientation);}

If you use this notice, when the iPhone/iPad rotation of the rotating direction you will get is all UIDeviceOrientationUnknown (screen direction down) and UIDeviceOrientationFaceUp (screen direction), which are all the values in the enumeration

Typedef NS_ENUM (NSInteger, UIDeviceOrientation) {UIDeviceOrientationUnknown, UIDeviceOrientationPortrait, Device oriented home button / vertically on the bottom UIDeviceOrientationPortraitUpsideDown, Device oriented home button / vertically on the top UIDeviceOrientationLandscapeLeft, Device oriented home button / horizontally on the right UIDeviceOrientationLandscapeRight, Device oriented home button / horizontally on the left UIDeviceOrientationFaceUp, oriented flat / / Device face, up UIDeviceOrientationFaceDown Device flat face down / oriented, __TVOS_PROHIBITED};

If only the monitor screen you can monitor UIApplicationDidChangeStatusBarOrientationNotification notification, i.e.:

[[NSNotificationCenter defaultCenter] selector:@selector (statusBarOrientationChange:) name:UIApplicationDidChangeStatusBarOrientationNotification addObserver:self object:nil];

At this point, the following circumstances will monitor the notification:

UIDeviceOrientationPortrait UIDeviceOrientationPortraitUpsideDown UIDeviceOrientationLandscapeLeft UIDeviceOrientationLandscapeRight

2, through the method of willRotateToInterfaceOrientation:duration to judge

- (void) willRotateToInterfaceOrientation: (UIInterfaceOrientation) toInterfaceOrientation duration: (NSTimeInterval) duration{if (UIInterfaceOrientationIsLandscape (toInterfaceOrientation) (NSLog) {// cross screen "@");}}} else {// vertical screen

The screen can be judged according to the value of UIInterfaceOrientation, UIInterfaceOrientation:

Typedef NS_ENUM (NSInteger, UIInterfaceOrientation) {UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown, UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait, UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown, UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight, UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft} __TVOS_PROHIBITED;

Two, mandatory individual interface vertical screen display

1, through the appdelegate proxy method application:supportedInterfaceOrientationsForWindow implementation:

- (UIInterfaceOrientationMask) application: (UIApplication *) application supportedInterfaceOrientationsForWindow: (nullable UIWindow *) window{if (_enablePortrait) {return UIInterfaceOrientationMaskPortrait} return UIInterfaceOrientationMaskLandscape |; UIInterfaceOrientationMaskPortrait;}

EnablePortrait is one of the BOOL value of the property in the appdelegate.h, if an interface only supports the vertical screen, it is set to YES, otherwise not tube, the following code in a controller:

The horizontal screen does not directly change the / / - (void) viewWillAppear: (BOOL) animated{AppDelegate *delegate (AppDelegate * [UIApplication) = sharedApplication].delegate; delegate.enablePortrait = YES;} - (void) viewWillDisappear: (BOOL) animated{[super viewWillDisappear:animated]; AppDelegate *delegate = (AppDelegate * [UIApplicationsharedApplication].delegate); delegate.enablePortrait = NO;}

After this is set, the controller does not support the cross screen display

2, through the method of shouldAutorotate and supportedInterfaceOrientations to achieve individual interface vertical screen:

- (BOOL) shouldAutorotate{YES return;} - (UIInterfaceOrientationMask) supportedInterfaceOrientations{return UIInterfaceOrientationMaskPortrait;}

ShouldAutorotate does support automatic rotation of supportedInterfaceOrientations means the direction of rotation, when added to the above two methods you will find what did, look at the official document:

IPad screen adaptation

we can find that the two methods need to be set in the root view, meaning that this page is really the direction of rotation is judged according to the two methods of the root view, if there is a navigation controller, in the ViewController shouldAutorotate will not be called, will call to the shouldAutorotate method, the navigation controller to solve the problem:
new BaseNavigationController inherited from UINavigationController, realization method

Whether the automatic rotation / (BOOL) shouldAutorotate{return self.topViewController.shouldAutorotate;} / / support direction - (UIInterfaceOrientationMask) supportedInterfaceOrientations{return self.topViewController.supportedInterfaceOrientations;} / / first direction is very important - (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation{return self.topViewController.preferredInterfaceOrientationForPresentation;}

ViewController navigation controller for the BaseNavigationController type, and the realization of the method:

- (BOOL) shouldAutorotate{return YES;} - (UIInterfaceOrientationMask) supportedInterfaceOrientations{return UIInterfaceOrientationMaskPortrait;} //- (UIInterfaceOrientationMask) supportedInterfaceOrientations{/ / return / / UIInterfaceOrientationMaskLandscape; //} start left cross screen, the supportedInterfaceOrientations method returns a collection must include UIInterfaceOrientationLandscapeLeft //- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation{/ return UIInterfaceOrientationLandscapeLeft //};

At this time you will find the screen support only vertical screen, cross screen no longer work, if the two method is not implemented, the default screen support
interface if most vertical screen, individual interface is cross screen, it is best to write a BaseViewController inherited from the base class of the UIViewController class, the realization method in the base class:

- (BOOL) shouldAutorotate{YES return;} - (UIInterfaceOrientationMask) supportedInterfaceOrientations{return UIInterfaceOrientationMaskPortrait;}

After the controller to create a successor to the BaseViewController, the controller is created by default on the vertical screen, the need for cross screen interface to re implement the supportedInterfaceOrientations method

- (UIInterfaceOrientationMask) supportedInterfaceOrientations {return UIInterfaceOrientationMaskLandscape;}

Three, forced interface only supports horizontal or vertical screen

1, through KVC, in ViewDidLoad to achieve the following code:

[[UIDevice currentDevice] numberWithInteger:UIDeviceOrientationLandscapeLeft] forKey:@ "orientation"]; [[self class] attemptRotationToDeviceOrientation]; setValue:[NSNumber;

The private variable here is not directly used by apple, but the use of KVC indirect method this method is called, can not be back to the shelves,
2, using NSInvocation call object message
/ / oK code is the use here. Here the message is called by NSInvocation

Use the code here is / / oK. Here the use of NSInvocation call object - (void) viewWillAppear: (BOOL) animated{[super viewWillAppear:animated]; if ([[UIDevice currentDevice]respondsToSelector:@selector (setOrientation:)] SEL (NSSelectorFromString) {selector = @ "setOrientation:"); NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:[UIDevice currentDevice]]; int Val = UIInterfaceOrientationLandscapeLeft; / / [invocation setArgument:& horizontal screen Val; atIndex:2]; [invocation invoke];}}

The first parameter to receive a pointer, also is to transfer the value of the time need to pass the
address of the second parameters: the need to specify several parameters method of value passing
note: set the parameters of the index is not from the beginning of 0, because the 0 has been occupied, 1 self (target) _cmd (selector) has been occupied already stated in the official document of NSInvocation,
(_cmd in the method of Objective-C said the current method is the same as self selector, said that the current method is called the object instance. )

[invocationsetArgument:& valatIndex:2];

Calling the invoke method of the NSInvocation object * as long as you call the invocation method of invoke, it means that you need to execute the specified method of the object in the NSInvocation object and pass the specified parameter

[invocation invoke];

Four, get the direction of the current screen

UIInterfaceOrientation currentOrient = [UIApplication sharedApplication].statusBarOrientation;

Five, iPad horizontal screen around tableView blank

- (void) viewDidLoad viewDidLoad] self.tableView {[super = [[UITableView; alloc]initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain]; self.tableView.delegate = self; self.tableView.dataSource = self; [self.view addSubview: self.tableView];} - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section{return 100;} - (UITableViewCell *) tableView: (* UITableView) tableView (NSIndexPath * cellForRowAtIndexPath:) indexPath{static NSString *indentifier @ = "cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:indentifier]; if (! Cell) {cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:indentifie R];} cell.textLabel.text = [NSString "cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:indentifier];"]; return cell;}

Results:

IPad screen adaptation

is used as a cell system, the following problems about the blank, which is within the margin system of cell automatic setting, we want to customize cell to replace cell, add a button cell to do the test:

- (instancetype) initWithStyle: (UITableViewCellStyle) style reuseIdentifier: (NSString *) reuseIdentifier{if (self [super = initWithStyle:style reuseIdentifier:reuseIdentifier]) {self.testBtn = [[UIButton = alloc]init]; self.testBtn.backgroundColor [UIColor orangeColor]; [self addSubview:self.testBtn];} return self;} - (void) layoutSubviews{[super layoutSubviews]; self.testBtn.frame = CGRectMake (0, 10, [UIScreen mainScreen].bounds.size.width, 30);}

At this point, you only need to replace the system cell in the controller as a custom cell

- (UITableViewCell) tableView: (UITableView * tableView) cellForRowAtIndexPath: (NSIndexPath *) indexPath{static NSString *indentifier @ = "cell"; TestCell *cell = [tableView dequeueReusableCellWithIdentifier:indentifier]; if (cell! = [[TestCell) {cell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:indentifier]}; return cell;}

Result´╝Ü

IPad screen adaptation

You can see the right side of the screen under the horizontal blank, because the horizontal screen is the tableView of the frame or vertical screen when the frame, and therefore should be in the screen rotation to set up the tableView frame:

- (void) willRotateToInterfaceOrientation: (UIInterfaceOrientation) toInterfaceOrientation duration: (NSTimeInterval) self.tableView.frame = [UIScreen mainScreen].bounds;}

This screen is cell to fill the entire screen
note: if you set BTN in cell frame is in the init method, cross screen cell right is still blank, so standardized wording is to set up the frame in layoutSubviews, such as:

- (instancetype) initWithStyle: (UITableViewCellStyle) style reuseIdentifier: (NSString *) reuseIdentifier{if (self [super = initWithStyle:style reuseIdentifier:reuseIdentifier]) {self.testBtn = [[UIButton (alloc]initWithFrame:CGRectMake 0, [UIScreen 10, mainScreen].bounds.size.width, 30); self.testBtn.backgroundColor = [UIColor orangeColor]; [self addSubview:self.testBtn];} return self;}

Careful observation will find the tableViewd split line indentation, in order to allow the tableView split line custom and in order to fit ios7, 8, more than 9 of the system, should be in the cell will appear:

- (void) tableView: (UITableView * tableView) willDisplayCell: (UITableViewCell * cell) forRowAtIndexPath: (NSIndexPath * indexPath) {if ([cell respondsToSelector:@selector (setPreservesSuperviewLayoutMargins:)] [cell) {setPreservesSuperviewLayoutMargins:NO]}; if ([cell respondsToSelector:@selector (setLayoutMargins:)] {[cell setLayoutMargins:UIEdgeInsetsZero]}});

And add code in viewDidLoad:

If ([self.tableView respondsToSelector:@selector (setCellLayoutMarginsFollowReadableWidth:)])} {self.tableView.cellLayoutMarginsFollowReadableWidth = NO; if ([self.tableView respondsToSelector:@selector (setSeparatorInset:)] [self.tableView (setSeparatorInset:UIEdgeInsetsMake) {0, 16, 0, 16]);}

At this point you can achieve the separation of the line within the margin, but you can also hide the system partition lines, their own custom cell in the final code set
:

@implementation //cell code TestCell - (instancetype) initWithStyle: (UITableViewCellStyle) style reuseIdentifier: (NSString *) reuseIdentifier{if (self [super = initWithStyle:style reuseIdentifier:reuseIdentifier]) {self.testBtn = UIButton + alloc]init] = [UIColor; self.testBtn.backgroundColor orangeColor]; [self addSubview:self.testBtn];} return self;} - (void) layoutSubviews{[super layoutSubviews]; self.testBtn.frame = CGRectMake (0, 10. [UIScreen mainScreen].Bounds.size.width, 30);} / / @end controller #import code "ViewController.h" #import "TestCell.h" @interface (ViewController) < UITableViewDelegate, UITableViewDataSource> @property (nonatomic, strong) UITableView * tableView; @e Nd @implementation ViewController - viewDidLoad [super viewDidLoad] (void) {self.tableView = [[UITableView; alloc]initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain]; self.tableView.delegate = self; self.tableView.dataSource = self; [self.view addSubview:self.tableView]; if ([self.tableView respondsToSelector:@selector (setCellLayoutMarginsFollowReadableWidth:)])} {self.tableView.cellLayoutMarginsFollowReadableWidth = NO; if ([self.tableView respondsToSelector:@selector (setSeparatorInset:)] [self.tableView) {setSeparatorInset:UIEdgeInsetsMake (0, 16, 0. 16]);}} - (void) willRotateToInterfaceOrientation: (UIInterfaceOrientation) toInterfaceOrientation duration: (NSTime Interval duration{self.tableView.frame = [UIScreen mainScreen].bounds);} - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section{return 100;} - (void) tableView: (UITableView * tableView) willDisplayCell: (UITableViewCell * cell) forRowAtIndexPath: (NSIndexPath * indexPath) {if ([cell respondsToSelector:@selector (setPreservesSuperviewLayoutMargins:)]) {[cell setPreservesSuperviewLayoutMargins:NO];} if ([cell respondsToSelector:@selector (setLayoutMargins:)])} {[cell setLayoutMargins:UIEdgeInsetsZero];} - (UITableViewCell *) tableView: (* UITableView) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath{static NSString *indentifier @ = "cell"; TestCell *cell [tableView = dequeueReusableCellWithIdentifier:indentifier]; if (cell! = [[TestCell) {cell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:indentifier]}}; return cell; @end

Six, iPhone adapter, iPad adapter and vertical screen screen settings

Can be set as follows:

IPad screen adaptation
IPad screen adaptation

I noticed that some projects can be directly set iPhone and iPad screen, the status bar style, but my new projects did not, nor the Internet to find information, know the trouble that the reader, as shown in fig.:

IPad screen adaptation

Last

1, inherited from the UIView class to set the best child control frame in the layoutSubViews method, since UIViewController, UITableViewController inherits the controller layout, the best UICollectionController in the viewWillLayoutSubviews, this screen switch instead of setting the frame
2, willRotateToInterfaceOrientation:duration: has been abandoned after the ios8, recommend the use of viewWillTransitionToSize: withTransitionCoordinator:

pit

In 1, viewWillTransitionToSize: in the withTransitionCoordinator: method to obtain the screen width and height: [UIScreen mainScreen].bounds.size.width, this method is executed before the screen rotation, arguably the screen width and height is rotating before the screen aspect, but some cases have problems and issues:

IPad screen adaptation

Four state
problem:
1, Upside Down Launch Screen check, File selected LaunchScreen
2, Upside Down Launch Screen check, File empty
3, uncheck Upside Down, Launch Screen File LaunchScreen
4, select uncheck Upside Down, Launch Screen File
and then we print in empty the controller in the screen width

#define kSrceenW [UIScreen mainScreen].bounds.size.width (void) viewWillTransitionToSize: (CGSize) size withTransitionCoordinator: (id< UIViewControllerTransitionCoordinator> Coordinator) {[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; NSLog (@%f%f ", [UIScreen mainScreen].bounds.size.width, kSrceenW);}

According to print the results we find that 2, 3, 4 in three cases of printing is the rotation before the screen width, 1 printing is after the rotation of the screen width, hole, so we’d better use method of parameter size (view controller size) screen adaptation