iOS11和iPhoneX适配的一些坑
本文转载于:
导航栏
导航栏高度的变化
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适配的一些坑,希望对大家有所帮助