iOS自动布局

Storyboard中用Auto Layout的“Bug”

在storyboard中使用自动布局,根控制器为一个UITableView,所有的cell的行高根据cell内容的多少动态变化(类似微博、微信朋友圈等应用)。

链接地址:demo

据此,我根据Cell的内容获取Cell内的labelUIImageView的frame,然后在layoutSubview方法中根据frame来计算最终的行高,然后,在controller中通过代理方法拿到行高。
这是很常规的一个开发思路,可是在storyboard开发中使用prototype(原型)cell的方式来实现却遇到了问题...

1.首先,我在StoryBoard里面使用prototype(原型)cell,而且没有改ViewController属性检测器中的simulation Metricssize

<img src="http://upload-images.jianshu.io/upload_images/2473291-318b2b21411c5051.png" width="400" height="400" alt="不设置此处的尺寸"/>

2.然后,我给cell中的所有的子控件设置了约束,并且确认无误,没有警告和错误,然后我update了一下所有控件的frame(注意:这里如果不更新所有控件的frame的话,storyboard便会给你报黄色警告,提示你期望的大小和真实的大小不相同,截图如下

<img src="http://upload-images.jianshu.io/upload_images/2473291-2a660988870a8925.png" width="400" height="300" alt="ExpectedFrame和ActualFrame的警告"/>

3.解决上面的办法也很简单,点击警报,点击Fix(修复)或者选中所有的控件,点击下方设置约束按钮中最右边的一个,选择"Update Frame"就可以了

<img src="http://upload-images.jianshu.io/upload_images/2473291-3292bacfb3423660.png" width="400" height="400" alt="修复上述警报的冲突"/>

4.设置完约束,我需要分别实现模型中的逻辑,和自定义的cell中的逻辑

4.1. 模型类从网络获取数据,使用的是异步子线程,下载完成后回调,切换主线程给ViewController中的数据数组赋值。

4.2. 给自定的cell内的子控件赋值写在了UITableViewDatasource的返回cell的方法中,但是,要求cell内的副标题Label的显示或不显示,取决于主标题Label的行数,如果主标题只显示1行,那么就显示副标题,相反,就不显示副标题。

这个逻辑才是重点
我在cell的layoutSubviews方法中获取主标题的frame,可是,无论如何改变主标题Label的约束,通过layoutSubviews方法获取到的frame始终不变。这里引起了我的怀疑,因为layoutSubviews方法的解释是当父控件的frame发生改变的时候,会调用此方法。但是实际来看在layoutSubviews方法中cell内的控件的frame仍然未发生变化,还是storyboard中Update Frames之后的值!!

但是当执行完layoutSubviews方法后,界面就已经能够正常地显示出来了,并且大小都正常,但是在layoutSubviews方法里打印的Label的frame却不正确,这就很奇怪!

副标题不正常的情况

于是,我继续猜想,这可能是由于约束设置完成之后,需要通过很多计算,而产生一个时间差,所以就使得在layoutSubviews方法执行的那一瞬间,无法立即计算出主标题的正确的frame。

接着,我寻找其他的思路,发现有一个方法layoutIfNeeded,这个方法的解释是:Lays out the subviews immediately.在调用这个方法后,立即布局该控件的子控件,因此,我试着在调用主标题Label的getter方法之前,调用layoutIfNeeded这个方法,结果就成功了。

正常的label显示情况.jpg

得出总结:当父控件的frame发生变化的时候,会调用它的layoutSubviews方法,但是,此时我们的约束还没有计算好所有子控件的frame值,所以,要在layoutSubviews方法内获取子控件的frame,可能就会拿到一个错误的frame值

在解决这个Bug的同时,还遇到一个小插曲,当属性检测器使用的是默认的大小的时候,如果勾选了storyboard中的ViewController属性检测器的Refreshing中的Enabled选项,则会出现在刚开始进入应用的时候,就会加载self.refreshControl 的title 内容

使用storyboard默认的大小

但是当我不进行其他任何的操作,而仅仅只是把属性检测器中模拟器的size属性设置为一个其他的大小时,就不会有上述的效果了

设置一个指定的尺寸之后.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容