我为什么要说UIStackView在iOS11上可能会影响子试图的布局
呢?因为我大概找到了因为 UIStackView
而引发出来的问题,没有找到问题的关键所在,也没有找到解决方法。
事情大概是这个样子的,我因为要做一款个人的 APP
,就借鉴了一下滴滴出行的 UI
界面,设计成下面的样子。
当时就准备把下面的做成一个控件
我说干就那就干,立马在 Github
立项,开始风风火火的制作起来。(这就是我的 Github
那么多废弃的坑了)
https://github.com/Share-Parking/ShareParking-Swich
大家可以前往 developer
分支查看此项目的进度,为了更加方便封装。我使用了 Framework
的方式来做这个控件。
使用 Framework
这种方式其实有几个好处的,我慢慢的说一下究竟有哪些好处。
- 可以支持
Playground
进行界面的边写边调试 - 支持
Swift
转换成OC
在OC
工程运行 - 可以使用
Carthage
很方便的打包成Framework
接入Carthage
和Cocoapods
- 可以一边练习
Swift
一边写轮子
唯一的缺点是不支持 iOS8
以下,没事我这个轮子还不支持 iOS9
以下呢?
起先在我 Playground
运行显示和交互十分的正常,但是在例子里面就表现的不正常了。
我觉得这个不正常应该来源于我的习惯,如果不是因为我的习惯,绝对还发现不了。
我的习惯测试控件都喜欢把初始的位置设置到(0,0)
。
下面是我测试代码
let swich = SPSwich(frame: CGRect(x: 0, y: 0, width: 200, height: 100))
self.view.addSubview(swich)
这两句代码是我从 Playground
直接拷贝过来的,Playground
表现的结果如下。
但是同样的代码放在我的例子上面就表现成下面的样子了。
我们可以看到当我们进行切换的时候,我们的试图明显的被挤压了。我们目测被挤压的高度应该是20
高度。
为什么会被20
高度呢?20
高度代表着什么呢?
一个大胆的想法出现在我的脑海里面,那就是是不是20
代表着状态栏的高度,如果我们设置的位置在导航栏的下面,就可以不偏移了。
我带着半信半疑的态度,立马把代码设置成下面的样子。
let swich = SPSwich(frame: CGRect(x: 0, y: 20, width: 200, height: 100))
self.view.addSubview(swich)
果然验证了我的猜想,但是为什么突然就出现影响子试图的位置和大小了呢?
我们之前如果想设置全屏的布局就需要设置一个属性,那就是下面的代码。
self.automaticallyAdjustsScrollViewInsets = false
但是不幸的是这个属性竟然在 iOS11
以上被废弃了,改用了UIScrollView
一个新的属性进行代替。
@available(iOS 11.0, *)
open var contentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentBehavior
虽然有替代的方案可以解决,但是我们这个例子当中并没有用到 UIScrollView
。
我们假如继续大胆的猜测,会不会我们使用 UIStackView
的影响导致的呢。
我们为了验证这个猜想,立马去掉了我们使用 UIStackView
的布局,使用设置 Frame
的方式设置我们里面的子试图。
我们换成常规的使用 Frame
进行布局的时候,果然发现表现正常了。
到目前位置,暂没有找到因为 UISatckView
里面那个属性在 iOS11
废弃了,导致这个问题的出现。
现在的解决办法有两个:
- 使用手动计算的方式布局子试图
- 使用设置约束设置子试图
- 继续使用 UIStackView 但是布局在 y >= 20
在开发的过程中,直接布局在 y<20
上面。并且使用 UIStackView
布局应该少之又少。
这虽然是一个问题的存在,但是不影响大家平时开发。
如果那个大神知道这个问题什么原因导致并知道解决办法的话,可以联系我帮助修正。