美文网首页iOSios新版本特性与适配
iOS11就问你一句“惊不惊喜?意不意外?”5.8的苦笑。。。。

iOS11就问你一句“惊不惊喜?意不意外?”5.8的苦笑。。。。

作者: 五八四十 | 来源:发表于2017-09-28 10:19 被阅读707次

公司的应用是居于iOS8上以上的,页面显示在iOS8上〜iOS10都没有问题,但是,iOS11beta版显示出现各种问题,真是顾客虐你千百遍,你待顾客如初恋,苹果搞事,我们也只能暗暗的承受.😜

搞事一:导航栏

1.导航栏高度变化

导航栏在iOS10之前都是默认的64P,但是,到了iOS10就不单单是64P了,可以看一下系统的信息应用程序,在iOS11添加了大标题,效果如下图1:

图1.png

的导航栏的结构,看图2,3,4:

图2.png

图3.png

图4.png

在上面三幅图可以知道,在iOS11导航栏多了一个LargeTitleView,专门显示大字标题用的,整个导航栏的高度达到了96P,这不包括状态栏的高度,也就是说,整个应用程序顶部高度达到了116p,其中statusbar = 20,title = 44,largetitle = 52,不过默认是64p;当然,iPhoneX的高度会更高点,如果不显示大字标题,顶部的高度也达到了88,statusbar = 44,title = 44,如果显示大字标题,则高度变成了140,statusbar = 44,title = 44,largetitle = 52,也就是说,iPhoneX的刘海高度为24p,大字标题如下图:

iPhoneX之前的机型巴纽

iPhoneX.png

2.导航栏的图层变化

iOS11之前导航栏的标题是添加在UINavigationItemView上面,而navigationBarButton则直接添加在的导航栏上面;如果设置了titleview的,则titleview的也是直接添加在的导航栏上面,如图5:

图5.png

在iOS11之后,苹果添加了新的类来管理,的导航栏会添加在_UIButtonBarStackView上面,而_UIButtonBarStackView则添加在_UINavigationBarContentView上面;如果没有给titleview的赋值,则titleview的会直接添加在_UINavigationBarContentView上面,如果赋值给了titleview的,则会新生成_UITAMICAdaptorView,把titleview的添加在这个类上面,这个类会添加在_UINavigationBarContentView上面,如下图6,7:

图6.png

图7.png

3.导航栏的边距变化

在iOS11对导航栏里面的物品的边距也做了调整:

(1)如果只是设置了titleview的,没有设置barbutton,把titleview的的宽度设置为屏幕宽度,则titleview的距离屏幕的边距,iOS11之前,在iPhone6p上是20P,在iPhone6p之前是16P; iOS11之后,在iPhone6p上是12P,在iPhone6p之前是8P。

(2)如果只是设置了barbutton,没有设置titleview的,则在iOS11里,barButton距离屏幕的边距是20P和16P;在iOS11之前,barButton距离屏幕的边距也是20P和16P。

(3)如果同时设置了titleview的和barButton,则在iOS11之前,titleview的和barbutton之间的间距是6P,在iOS11上titleview的和barbutton之间无间距,如下图8,9:

图8.png

图9.png

4.App需要实现导航栏左右按钮边距为0

在iOS11之前,可以设置一个宽度为负的navigationBarButton,将按钮挤到边缘,变相实现0边距的导航栏按钮,但是,这招在iOS11失效了,原因在于_UIButtonBarStackView,这个iOS9之后出来的,用来相对布局的组件,限制了子视图的布局。那怎么搞呢?

想要的方法有几个:

(1)在viewWillAppear里面,将_UIButtonBarStackView取出来,直接设置它的x坐标。

(2)设置titleView,然后将按钮添加在titleView上面,根据不同的边距做偏移。

方法一:

遇到的问题,在viewDidLoad中,viewWillAppear中,viewWillLayoutSubviews,viewDidLayoutSubviews里面都取不到_UIButtonBarStackView,只有在viewDidAppear里才能取到值,这样就会在页面显示了之后才开始移动navigationBarButton,显然这样体验不好,所以,暂时通过掉。

方法二:

。这个做法完全可以做到0边距,但是,问题来了,就是点击区域的问题因为左右navigationBarButton的点击区域是超出父视图的,所以,点击不到这好办,重写titleview的的则hitTest方法就好。嘿嘿嘿,问题没有那么简单。之前在iOS11的图层结构就解释过,titleview的会被添加在_UITAMICAdaptorView上面,而重点是,这个视图也有边距,所以,单单重写titleview的的则hitTest方法还不够,那怎么解决呢?我的办法就是写一个视图的类别,钩所有视图的则hitTest方法,在里面判断是否是iOS11以上,是否是_UITAMICAdaptorView类,如果都满足条件,则可以搞事了.😜演示

搞事二:列表的变化

1.automaticallyAdjustsScrollViewInsets

在iOS11之前,如果想要滚动视图不偏移64P,则需设置automaticallyAdjustsScrollViewInsets = NO,但是这个属性在iOS11直接被遗弃了😳:

@property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsetsAPI_DEPRECATED_WITH_REPLACEMENT("Use UIScrollView's contentInsetAdjustmentBehavior instead", ios(7.0,11.0),tvos(7.0,11.0));

所以,看一下contentInsetAdjustmentBehavior是何方神圣:

typedef NS_ENUM(NSInteger, UIScrollViewContentInsetAdjustmentBehavior) {UIScrollViewContentInsetAdjustmentAutomatic, // Similar to .scrollableAxes, but will also adjust the top & bottom contentInset when the scroll view is owned by a view controller with automaticallyAdjustsScrollViewContentInset = YES inside a navigation controller, regardless of whether the scroll view is scrollableUIScrollViewContentInsetAdjustmentScrollableAxes, // Edges for scrollable axes are adjusted (i.e., contentSize.width/height > frame.size.width/height or alwaysBounceHorizontal/Vertical = YES)UIScrollViewContentInsetAdjustmentNever, // contentInset is not adjustedUIScrollViewContentInsetAdjustmentAlways, // contentInset is always adjusted by the scroll view's safeAreaInsets} API_AVAILABLE(ios(11.0),tvos(11.0));/* Configure the behavior of adjustedContentInset.Default is UIScrollViewContentInsetAdjustmentAutomatic.*/@property(nonatomic) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior API_AVAILABLE(ios(11.0),tvos(11.0));

看起来这和iOS11搞的safeArea有关,这个先放一遍,看看怎么适配:

#define  adjustsScrollViewInsets_NO(scrollView,vc)\do { \_Pragma("clang diagnostic push") \_Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \if ([UIScrollView instancesRespondToSelector:NSSelectorFromString(@"setContentInsetAdjustmentBehavior:")]) {\[scrollView  performSelector:NSSelectorFromString(@"setContentInsetAdjustmentBehavior:") withObject:@(2)];\} else {\vc.automaticallyAdjustsScrollViewInsets = NO;\}\_Pragma("clang diagnostic pop") \} while (0)

上面是公司里面一个大神写的,这样就可以在Xcode8上面跑了。

2.tableView默认使用自调整大小

这个配合estimatedRowHeight,estimatedSectionFooterHeight,estimatedSectionHeaderHeight使用,可以预估高度。之前,设置高度为0时,需要设置高度= 0.1,才会起作用,如果直接设置为0,则会使用默认高度,由于自动使用预估高度,所以,忽略了设置的高度,使原来的高度增大了。只要把这几个属性设置为0就可以解决。

搞事三:iPhoneX底部的TabBar的高度改变

iPhoneX不止多了刘海,底部还有一个半角的矩形,使得的TabBar多出来了34P的高度,不过不管导航栏和的TabBar一般系统都会自动适配safeArea。

iPhoneX tabbar.png

总结:

iOS11系统改变还是比较大的,某些地方需要注意适配,不然会出现很奇怪的现象。暂时,在iOS11遇到这么多坑,以后遇到会继续分享的。

相关文章

网友评论

  • loghm:你好,我在适配iOS 11的时候,会出现导航栏被UIVisualEffectView遮挡住的情况,我自定义的返回按钮也不见了,请问这种可能是什么原因?
    五八四十:@loghm 首先你先要明确你的按钮添加在什么视图上呢?
  • _码奴:我想知道怎么去掉ios11之后titleView两边的间距,有什么办法吗
    五八四十:由于iPhone X的机型比较特别,适配也不可能只针对一种去考虑,你要根据机型去判断视图位置就可以。

本文标题:iOS11就问你一句“惊不惊喜?意不意外?”5.8的苦笑。。。。

本文链接:https://www.haomeiwen.com/subject/uvdmextx.html