digression

This is the content of an internal technology sharing meeting of the company, which is divided into three parts:

  • Xcode9 new features
  • IOS 11 adaptation
  • IPhone X adaptation This is part two, so stay tuned if you need to. The first part of Xcode9’s new features gets down to business

Stir up a feud

IOS 11 is here, and as an iOS developer, that means it’s too late to adapt to iOS 11. But is still in Beta stage our technology and da uncle first experience, and careful to run again play side tentacles TV and recording APP and APP tentacles, in addition to a by a third party library WebViewJavascriptBridgeBase cause of severe crash, There is basically no problem with the two apps under iOS 11, and the problems found have been fixed by Darius in advance. So there has been no adaptation work in the group, but focus on the recent development of the large version. It has been observed that apps downloaded directly from the AppStore run on iOS 11 without any problems, but if they run after using Xcode 9 Building, there will be more or less problems. Because Xcode 9’s Base SDKS are based on iOS 11. So it still needs to be adapted.

Never gone

Through reading the peer cases of iOS 11 adaptation online and combining with the actual problems of Zhushou TVAPP, the following points may be needed for adaptation. Finding the root of the problem will help us solve it. Why does this happen? Let’s take a look at what’s new in iOS 11. Here are just some of them and the ones that are relevant to today’s topic. Check out what’s New in iOS 11 for details.

UIViewController and UIView
Major changes:
  • UIViewControllerabandonedLayoutGuide. After iOS7, in order to assist Autolayout layout system, Apple addedUILayoutSupportThe agreement. That a lot of people misstopLayoutGuide.bottomLayoutGuide.
@interface UIViewController (UILayoutSupport)
// These objects may be used as layout items in the NSLayoutConstraint API
@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));
@property(nonatomic) UIEdgeInsets additionalSafeAreaInsets API_AVAILABLE(ios(11.0), tvos(11.0));Copy the code

These two properties are readonly and are not normally used. Their main function is to help the Controller’s View know where to start the layout and where to end the layout. When using SB or XIB file layouts, you can set up reference points to start and end the layout. API_DEPRECATED_WITH_REPLACEMENT has been marked in iOS 11. Instead, UIView’s new APIsafeAreaInsets.

LayoutGuide

  • UIView increase safeAreaInsets: UIEdgeInsets safety concept. LayoutGuide used as an alternative to auxiliary automatic layout. The security zone defines the visible area of the layout View after the various bars are removed. This property is readonly. To change it, you need to operate the additionalSafeAreaInsets property of UIViewController.

    Simple understanding is to remove the system of various bars and left and rightMargin (if set)After the available layout area.

    The light blue area in the figure is the security zone:

    safeAreaInsets

    SafeAreaInsets = {(0,0),(0,0)} correspond to (top,left,bottom,right) if the control on the View is not blocked. SafeAreaInsets = {(20,0),(0,0)}

    Note: if using SB, XIB layout UI,safeAreaInsetsThe minimum supported version is iOS 9.0. For compatibility reasons, tentacle TVS can’t use security zones.

  • UIViewController automaticallyAdjustsScrollViewInsetsAPI. This is a bool property that describes whether the contentInsets of the scrollView are automatically adapted. When the value is true, the contents of the scrollView will not be blocked by the various bars visible to the system (Statusbar, navigationBar, tabBar, toolBar), generally resulting in tableView, collectionView, The content of the scrollView drops the height of the bar by pixels. If automatic adjustment is not required, set the value to false.

  • APIadditionalSafeAreaInsets UIViewController change new association View security area. You can add or subtract the value of a security zone to meet custom UI requirements. ViewSafeAreaInsetsDidChange and provide method for changes in the security area, the adjustment of the layout.

  • Accordingly, increase enumerated attribute contentInsetAdjustmentBehavior UIScrollView, describe how the scrollView adjustment contentInset (it was adjusted adjustedContentInset properties), fit the safety area. Finally, UIscrollView’s contentInset value is the sum of adjustedContentInset and safeAreaInsets.

    There are four optional values:

      typedef NS_ENUM(NSInteger.UIScrollViewContentInsetAdjustmentBehavior) {
              UIScrollViewContentInsetAdjustmentAutomatic./ / similar to automaticallyAdjustsScrollViewInsets
              UIScrollViewContentInsetAdjustmentScrollableAxes.// Automatically adjust the scroll axis upward
              UIScrollViewContentInsetAdjustmentNever.// No adjustments are made
              UIScrollViewContentInsetAdjustmentAlways.// contentInset is equal to View safeAreaInsets
          } API_AVAILABLE(ios(11.0),tvos(11.0));Copy the code

    New scrollViewDidChangeAdjustedContentInset UIScrollViewDelegate method, when adjustedContentInset notify the user to change the layout adjustment.

Conclusion:

  • If security zones are enabled in SB or XIB layout, IB will refer to security zones for layout.
  • If a security zone is not used as a reference in the layout, the system does not perform adaptive actions on the layout. You can adjust the layout by changing the callback method of the security zone.
  • If it isUIscrollViewOr subclasses, if setUIScrollViewContentInsetAdjustmentBehaviorIs not equal toUIScrollViewContentInsetAdjustmentNever, the system automatically ADAPTSUIScrollViewAll contents are in the safe area to ensure that the contents are not covered by various bars.
The change of the NavigationBar

NavigationBar has a contentView that has a titleLable on it when the title is opened. NavigationBar’s titleView supports automatic layout. Requires the user to automatically open the View added to it.

Location permissions

In iOS11 original NSLocationAlwaysUsageDeion was downgraded to a NSLocationWhenInUseUsageDeion. In. Plist file configuration NSLocationAlwaysAndWhenInUseUsageDeion, system box will pop up, use requestAlwaysAuthorization access permissions.

Other changes
  1. Set UIBarItem. LandscapeImagePhone and UIBarItem. LargeContentSizeImage to fit under the portrait and landscape BarItem ICONS and double-click the icon for the enlarged, if use PDF resource map, The system will automatically extract the corresponding icon from the PDF resource graph, so you do not need to set the above properties.
  2. NavigationBar. PrefersLargeTitles new headline = true attribute, headline an control shows the enumerated: navigationItem. LargeTitleDisplayMode enumerated attribute:

    - automatic: automatically saves the last value. - always: always displays the title. - never: never displays the titleCopy the code
  3. Navigation integrates with searchBar. NavigationItem. SearchController attribute assignment can be integrated searchBar below the navigationbar, NavigationItem. HidesSearchBarWhenScrolling attribute controls whether hidden automatically when rolling.

  4. Make sure to avoid custom views with size 0 and implement the intrinsicContentSize method to provide the default size.

  5. Turn on self-sizing and set the following attributes to invalidate height estimation:

         tableView.estimatedRowHeight = 0 
    
         tableView.estimatedSectionHeaderHeight = 0 
    
         tableView.estimatedSectionFooterHeight = 0Copy the code
  6. Add left and right swipe interaction to TableView.

  7. Ditching layoutMargins from iOS7 and replacing them with the new concept of secure zones. New directionalLayoutMargins. The corresponding layoutMargins. New systemMinimumLayoutMargins, when directionalLayout less than systemMinimumLayoutMargins, use systemMinimumLayoutMargins. New UIViewController = viewRespectsSystemMinimumLayoutMargins, default is FALSE. Set to TRUE, any value can be set.

New and old hatred

Now that you understand iOS 11, let’s take a look at some of the problems that come with it.

NavigationBar problem.

NavigationBar is generally used in three ways.

  1. Pure blood, using the tag control, is notNavigationBarAdd any controls to the.
  2. And lives inNavigationBarThere are custom controls on.
  3. No pedigree, totally custom. Hiding the systemnavigationBar, directly used the View instead.

For the above three cases:

  • For those of you in the first position, fortunately, you don’t need to adapt. (Very few people don’t customize)

  • People using the second pose may have problems with the incorrect position of the back button, titleView, and added controls.

  • People who use the third pose, great, on non-iphone X, no big deal.

UIscrollView, UItableView, UICollectionView content sinking problem.

After upgrading to iOS 11, I noticed that some pages with UItableView layout had an extra 20pt, 44pt, or 64pt at the top. That is, the sum of the heights of the Bar visible at the top. Including problems caused by using MJRefresh. It falls into this category.

Xcode9 package (iOS 11 SDK) page lag

When you upgrade Xcode9, you’ll find that, based on iOS 11, the tableView slides in a lump.

The request location box does not pop up

In iOS 11, some apps fail to pop up the system request permission dialog box when requesting location.

Return button position deviation problem

On iOS 11, the leftBarButtonItem or the right side is 20 pixels away from the margin.

Other problems

  1. useYYKitThe large picture preview controlYYPhotoGroupViewIn dismiss, some pages will shake a little bit.

A smile makes a smile

Now that you know what iOS 11 is going to do and what it’s going to bring. Well, let’s make it work. Let’s make it work.

NavigationBar problem.

  • becauseNavigationBarThe introduction of theAutoLayout, in the pastframeThe mode may be mispositioned. Before usingCGRectMakeZeroSelf-propping is no longer an option. Then use automatic layout. Or implement the followingViewMethod to provide the default size.
- (CGSize)intrinsicContentSize {
    return CGSizeMake(100.100);
}Copy the code
  • Added to theNavigationBarView can have various problems, try adding tocontentViewOn. And set constraints.
  • Back button problem, please set upframeIn the assigned tonavigationItem.leftBarButtonItem.

UIscrollView, UItableView, UICollectionView content sinking problem

Because controllerView abandoned automaticallyAdjustsScrollViewInsets, please use the UIScrollViewContentInsetAdjustmentNever to tell the system, not to adjust. Or set additionalSafeAreaInsets to add safeAreaInsets to offset.

Rolling jam problem

Because self-sizing is on by default in tableView. Set the following three properties to invalidate height estimation:

    tableView.estimatedRowHeight = 0 
    tableView.estimatedSectionHeaderHeight = 0 
    tableView.estimatedSectionFooterHeight = 0Copy the code

The request location box does not pop up

In iOSi11 original NSLocationAlwaysUsageDeion was downgraded to a NSLocationWhenInUseUsageDeion. Therefore, in the original project using requestAlwaysAuthorization location permissions, but not in the file configuration NSLocationAlwaysAndWhenInUseUsageDeion, system frame not pop up. You are advised to configure both the old and new keys in plIST.

Page bounce problem

Refer to content sink problem to solve.

Button offset problem

With iOS 11, navigationBar added a contentView to host barButtons added by developers. 20 pixels were added to the left and right sides. There are several solutions. If you just want to adjust the back button, you can use the system API directly:

@property(nullable.nonatomic.strong) UIImage *backIndicatorImage;
@property(nullable.nonatomic.strong) UIImage *backIndicatorTransitionMaskImage;Copy the code

This approach, however, can cause problems when multiple buttons are used. There are still 20 pixels. Adjusting UIButton imageEdgeInsets can also cause layout problems with multiple buttons. Like this post. There are also push and pop Settings. Modifying constraints causes some constraints to be lost. There’s also overwriting drawRect.

There’s no need to go to all this trouble. Create a new class that inherits from UINavigationBar and override layoutSubviews. If it’s ios11, set the layoutMargins on the contentView to the desired value. The core code is as follows:

@interface CustomNavigationBar:UINavigationBar
@end


const CGFloat LeftFiexSpace = 0;
const CGFloat RightFiexSpace = 8.0;

@implementation CustomNavigationBar
- (void)layoutSubviews {
    [super layoutSubviews];
    // Fix the margins on the left and right of ios 11
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@ "11.0")) {
        self.layoutMargins = UIEdgeInsetsZero;
        for (UIView *subview in self.subviews) {
            if ([NSStringFromClass(subview.class) containsString:@"ContentView"]) {
                subview.layoutMargins = UIEdgeInsetsMake(0, LeftFiexSpace, 0, RightFiexSpace);
                [selflayoutIfNeeded]; }}}}@endCopy the code

Replace the original NavigationBar with your own using KVC where the NavigationController is generated.

 UINavigationController *nvc = [super initWithRootViewController:rootViewController];    
    CSNavigationBar *naviBar = [[CustomNavigationBar alloc] init];
    [nvc setValue:naviBar forKey:@"navigationBar"];Copy the code

The last

If you write wrong, welcome to point out, have a better solution, also welcome to exchange.

Refer to the article

Apple’s official website for video tutorials

How do I set the back button

You may need to adapt iOS11 for your APP and this is basically a text version of the official video