In the ancient days of iPhone3 and iPhone4, the device size was fixed at 3.5 inches. There was no problem with fitting, just hard coding with the frame attribute of the view. Over time, As Apple’s devices became more diverse and larger, a simple frame could no longer solve the problem, so it introduced AutoLayout and SizeClasses to solve the problem. For those of you who have been working on iOS development, you’ll probably have to deal with some of the following adaptations:

  1. The default size of the root view of the rear view controller in iOS7 is to take up the entire screen, and if there is a translucent navigation bar it also extends under the navigation bar and status bar by default. This time I believe you to meet both iOS7 and the following versions of the large area of revision and special adaptation processing, especially the status bar height problem is particularly tricky.

  2. After the release of iOS11, especially the launch of iPhoneX device, the particularity of iPhoneX device is shown as the height of the status bar at the top changes from 20 to 44, and there is a safety zone of 34 at the bottom. When the landscape screen is displayed, the indentation of 44 on the left and right sides should be considered. All the layout code needs to be readapted and combed to be compatible with the iPhoneX and other devices, especially the height of the status bar and the bottom security zone.

Personally, I think these two releases are the ones iOS developers have come across that require a lot of layout changes. In order to fit perfectly we might have to write a lot of if and else and write a lot of macros and version compatibility for special processing. Of course, Apple has provided a number of solutions for the two major revisions:

  1. IOS7 provides the following properties for view controllers to address version compatibility issues:
@property(nonatomic,assign) UIRectEdge edgesForExtendedLayout NS_AVAILABLE_IOS(7_0); // Defaults to UIRectEdgeAll
@property(nonatomic,assign) BOOL extendedLayoutIncludesOpaqueBars NS_AVAILABLE_IOS(7_0); // Defaults to NO, but bars are translucent by default on 7_0.  
@property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets API_DEPRECATED_WITH_REPLACEMENT("Use UIScrollView's contentInsetAdjustmentBehavior instead", ios (7.0, 11.0), tvos (7.0, 11.0)); // Defaults to YES @property(nonatomic,readonly,strong) id<UILayoutSupport> topLayoutGuide API_DEPRECATED_WITH_REPLACEMENT("-[UIView safeAreaLayoutGuide]", ios (7.0, 11.0), tvos (7.0, 11.0)); @property(nonatomic,readonly,strong) id<UILayoutSupport> bottomLayoutGuide API_DEPRECATED_WITH_REPLACEMENT("-[UIView safeAreaLayoutGuide]", ios (7.0, 11.0), tvos (7.0, 11.0));Copy the code
  1. The concept of a safe zone is introduced in iOS11, which requires our actionable views to be placed in a safe zone, and provides the following extended properties for views and scrollviews:
@property (nonatomic,readonly(ios) UIEdgeInsets safeAreaInsets API_AVAILABLE (11.0), tvos (11.0)); - (void) safeAreaInsetsDidChange API_AVAILABLE (ios (11.0), tvos (11.0)); /* The top of the safeAreaLayoutGuide indicates the unobscured top edge of the view (e.g, not behind the status bar or navigation bar,if present). Similarly for the other edges.
 */
@property(nonatomic,readonly, strong) UILayoutGuide * safeAreaLayoutGuide API_AVAILABLE (ios (11.0), tvos (11.0));Copy the code
/* When contentInsetAdjustmentBehavior allows, UIScrollView may incorporate
 its safeAreaInsets into the adjustedContentInset.
 */
@property(nonatomic, readonly(ios) UIEdgeInsets adjustedContentInset API_AVAILABLE (11.0), tvos (11.0)); /* Also see -scrollViewDidChangeAdjustedContentInset:inThe UIScrollViewDelegate protocol. * / - (void) adjustedContentInsetDidChange API_AVAILABLE (ios (11.0), tvos (11.0)) NS_REQUIRES_SUPER; /* Configure the behavior of adjustedContentInset. Default is UIScrollViewContentInsetAdjustmentAutomatic. */ @property(nonatomic) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior API_AVAILABLE (ios (11.0), tvos (11.0)); /* contentLayoutGuide anchors (e.g., contentLayoutGuide.centerXAnchor, etc.) refer to the untranslated content area of the scroll view. */ @property(nonatomic,readonly, strong) UILayoutGuide * contentLayoutGuide API_AVAILABLE (ios (11.0), tvos (11.0)); /* frameLayoutGuide anchors (e.g., frameLayoutGuide.centerXAnchor) refer to the untransformed frame of the scroll view. */ @property(nonatomic,readonly, strong) UILayoutGuide * frameLayoutGuide API_AVAILABLE (ios (11.0), tvos (11.0));Copy the code

The exact meaning of these attributes is not mentioned here, but there is a lot of information about the meaning of these attributes on the Internet and in the Official Apple. From the above attributes, we can see that the solutions proposed by Apple revolve around solving the relationship between view and navigation bar, scroll view, status bar, and screen edge. Because iOS7 and iOS11 have the biggest changes in the relationship between the view in the controller and some of the things listed above.

NSLayoutConstraint and encapsulation improvements on iOS9

In the era of iOS6, apple launched AutoLayout, a technical solution that uses relative constraints instead of hard coding. However, bad method names and usage methods lead to a sharp increase in usage cost and code volume. For example, the following code:

    UIButton *button = [self createDemoButton:NSLocalizedString(@"Pop layoutview at center"."") action:@selector(handleDemo1:)]; button.translatesAutoresizingMaskIntoConstraints = NO; // Button uses AutoLayout [scrollView addSubview:button]; // The following code is iOS6 since its own constraint layout writing method, you can see that the code is large. [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]]; [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:10]]; [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:40]]; [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeWidth multiplier:1 constant:-20]];Copy the code

A simple button to a UIScrollView to the code, when using AutoLayout to implement a code storm problem. Constraint Settings have been greatly improved since iOS9. Apple has encapsulated constraint Settings and provided three classes: NSLayoutXAxisAnchor, NSLayoutYAxisAnchor, NSLayoutDimension to simplify the setting of constraints, the same functionality, using a new class to write constraints is much cleaner:

    UIButton *button = [self createDemoButton:NSLocalizedString(@"Pop layoutview at center"."") action:@selector(handleDemo1:)]; button.translatesAutoresizingMaskIntoConstraints = NO; // Button uses AutoLayout [scrollView addSubview:button]; [button.centerXAnchor constraintEqualToAnchor:scrollView.centerXAnchor].active = YES; [button.topAnchor constraintEqualToAnchor:scrollView.topAnchor constant:10].active = YES; [button.heightAnchor constraintEqualToConstant:40].active = YES; [button.widthAnchor constraintEqualToAnchor:scrollView.widthAnchor multiplier:1 constant:-20].active = YES;Copy the code
UIStackView

There is also a UIStackView class in iOS9 that simplifies the way views are ordered from top to bottom or left to right. The use of UIStackView container views eliminates the need to add redundant dependency constraints to each child view. In a lot of practice the blocks of many applications are actually arranged in order from top to bottom or left to right. So if your application has minimum iOS9 support you can use this class as much as possible to build your application.

Placeholder view class UILayoutGuide

Before iOS9, the spacing and spacing between two views could not support floating and scalable Settings, and we could need to keep a floating size white space between two views. The solution is to add a transparent color UIView between them to handle. Anyway, any View needs to be rendered and drawn and that can affect the performance of the application to some extent, and in iOS9 there’s a placeholder View class UILayoutGuide, which acts like a normal View and you can constrain it, you can add it to the View, You can also use this placeholder view as a constraint dependency for other views, the only difference being that the placeholder view does not do any rendering or drawing, it only participates in layout processing. Therefore, the introduction of this class can largely solve those floating spacing problems.

Multi-screen fit

When our application may need to run in landscape and portrait at the same time and the layout of landscape and portrait is not consistent, and we want our application to have a different layout on a small screen than on a large screen (like the iPhone8 Plus and iPhoneX S Max), We might need to use Apple’s sizeclass technology. This is a concept that apple introduced in iOS8. However, we have seen very few examples of using the SizeClasses in the real world, and we have seen very few examples of using this technology in our development, so I think this is apple’s failed solution to the multi-screen adaptation. The SizeClasses are two different sizes: compressed and normal.

equipment The direction of type
iPhone4/5/6/7/X Vertical screen w:Compact h:Regular
iPhone4/5/6/7/X landscape w:Compact h:Compact
iPhone6/7Plus, iPhoneXMax Vertical screen w:Compact h:Regular
iPhone6/7Plus, iPhoneXMax landscape w:Regular h:Compact
All the Vertical screen w:Regular h: Regular
All the landscape w:Regular h: Regular
All iWatch Vertical screen w: Compact h: Compact
All iWatch landscape w: Compact h: Compact

The good news is that if your application is an application with a system navigation bar many of the adaptation issues can be solved very well, because the system already does a lot of things for you, you don’t need to do anything special. If one of your app’s interfaces is presented, or if you implement a custom navigation bar yourself, you may have to deal with adaptation issues yourself. And it’s even more complicated if your app may have vertical or horizontal screens.

Finally, in addition to the API provided by the system to solve all the adaptation problems, I also recommend my open source layout library: MyLayout. It supports both Objective-C and Swift versions. And with this library, all of the above adaptation problems are not a problem.


Welcome to ouyang Big Brother 2013Making the address