当前位置: 移动技术网 > 移动技术>移动开发>IOS > iOS11和iPhoneX适配的一些坑

iOS11和iPhoneX适配的一些坑

2019年07月24日  | 移动技术网移动技术  | 我要评论

本文转载于:

导航栏

导航栏高度的变化

ios11之前导航栏默认高度为64pt(这里高度指statusbar + navigationbar),ios11之后如果设置了preferslargetitles = yes则为96pt,默认情况下还是64pt,但在iphonex上由于刘海的出现statusbar由以前的20pt变成了44pt,所以iphonex上高度变为88pt,如果项目里隐藏了导航栏加了自定义按钮之类的,这里需要注意适配一下。

导航栏图层及对titleview布局的影响

ios11之前导航栏的title是添加在uinavigationitemview上面,而navigationbarbutton则直接添加在uinavigationbar上面,如果设置了titleview,则titleview也是直接添加在uinavigationbar上面。ios11之后,大概因为largetitle的原因,视图层级发生了变化,如果没有给titleview赋值,则titleview会直接添加在_uinavigationbarcontentview上面,如果赋值了titleview,则会把titleview添加在_uitamicadaptorview上,而navigationbarbutton被加在了_uibuttonbarstackview上,然后他们都被加在了_uinavigationbarcontentview上,如图:

所以如果你的项目是自定义的navigationbar,那么在ios11上运行就可能出现布局错乱的bug,解决办法是重写uinavigationbar的layoutsubviews方法,调整布局,上代码:

- (void)layoutsubviews {
  [super layoutsubviews];
  //注意导航栏及状态栏高度适配
  self.frame = cgrectmake(0, 0, cgrectgetwidth(self.frame), navibarheight);
  for (uiview *view in self.subviews) {
    if([nsstringfromclass([view class]) containsstring:@"background"]) {
      view.frame = self.bounds;
    }
    else if ([nsstringfromclass([view class]) containsstring:@"contentview"]) {
      cgrect frame = view.frame;
      frame.origin.y = statusbarheight;
      frame.size.height = self.bounds.size.height - frame.origin.y;
      view.frame = frame;
    }
  }
}

再补充一点,看了简书app适配ios11发现titleview支持autolayout,这要求titleview必须是能够自撑开的或实现了- intrinsiccontentsize方法

- (cgsize)intrinsiccontentsize {
  return uilayoutfittingexpandedsize;
}

uiscrollview、uitableview、uicollectionview

大家在ios11设备上运行出现最多问题应该就是tableview莫名奇妙的偏移20pt或者64pt了。。原因是ios11弃用了automaticallyadjustsscrollviewinsets属性,取而代之的是uiscrollview新增了contentinsetadjustmentbehavior属性,这一切的罪魁祸首都是新引入的safearea,关于safearea适配这篇文章ios 11 安全区域适配总结讲的很详细,感兴趣的可以看下,我直接贴适配代码,因为低版本直接用contentinsetadjustmentbehavior会报警告,所有定义了如下的宏(感谢@炒鸡范的指正,之前的宏犯了个低级错误...现改为)

#define adjustsscrollviewinsets(scrollview)\
do {\
_pragma("clang diagnostic push")\
_pragma("clang diagnostic ignored \"-warc-performselector-leaks\"")\
if ([scrollview respondstoselector:nsselectorfromstring(@"setcontentinsetadjustmentbehavior:")]) {\
  nsmethodsignature *signature = [uiscrollview instancemethodsignatureforselector:@selector(setcontentinsetadjustmentbehavior:)];\
  nsinvocation *invocation = [nsinvocation invocationwithmethodsignature:signature];\
  nsinteger argument = 2;\
  invocation.target = scrollview;\
  invocation.selector = @selector(setcontentinsetadjustmentbehavior:);\
  [invocation setargument:&argument atindex:2];\
  [invocation retainarguments];\
  [invocation invoke];\
}\
_pragma("clang diagnostic pop")\
} while (0)

还有的发现某些界面tableview的sectionheader、sectionfooter高度与设置不符的问题,在ios11中如果不实现 -tableview: viewforheaderinsection:和-tableview: viewforfooterinsection: ,则-tableview: heightforheaderinsection:和- tableview: heightforfooterinsection:不会被调用,导致它们都变成了默认高度,这是因为tableview在ios11默认使用self-sizing,tableview的estimatedrowheight、estimatedsectionheaderheight、 estimatedsectionfooterheight三个高度估算属性由默认的0变成了uitableviewautomaticdimension,解决办法简单粗暴,就是实现对应方法或把这三个属性设为0。

如果你使用了masonry,那么你需要适配safearea

if (@available(ios 11.0, *)) {
  make.edges.equalto()(self.view.safeareainsets)
} else {
  make.edges.equalto()(self.view)
}

iphonex

launchimage

关于iphonex(我就不吐槽刘海了...),如果你的app在iphonex上运行发现没有充满屏幕,上下有黑色区域,那么你应该也像我一样launchimage没有用storyboard而是用的assets,解决办法如图,启动图的尺寸为1125x2436,or you can ios开发时如何使用 launch screen storyboard。

tabbarcontroller

因为我们的项目用了第三方的tabbarcontroller,在iphonex运行,tabbar看起来怪怪的...估计作者要等到猴年马月才适配iphonex,项目又着急上线,就自己修改了第三方,主要是tabbar高度及tabbaritem偏移适配,iphonex由于底部安全区的原因uitabbar高度由49pt变成了83pt,可以通过判断机型来修改相关界面代码

#define kdevice_is_iphonex ([uiscreen instancesrespondtoselector:@selector(currentmode)] ? cgsizeequaltosize(cgsizemake(1125, 2436), [[uiscreen mainscreen] currentmode].size) : no)

目前遇到的就这些坑,欢迎大家指正补充~

作为一名ios开发人员,想到当年嘲笑android开发蛋疼的适配各种机型心情如图...

总结

以上所述是小编给大家介绍的ios11和iphonex适配的一些坑,希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网