摘要:原文链接约束优先级九宫格续,一个更优方案这两个项目的源码均在我的,如有需要直接下载下来试一试。依然是九宫格格子长宽,单张大图长宽。还是保持了底部的与和九宫格的间距都是。因为是九宫格,所以高度由每排第一张图存不存在决定。
原文链接:AutoLayout:constraint priority 约束优先级(九宫格续,一个更优方案)
这两个项目的源码均在我的 github,如有需要直接下载下来试一试。
模仿微博客户端
自适应高度测试用项目
上一篇:AutoLayout:UITableViewCell 自适应高度的一个例子
之前因为觉得麻烦,没有在那个项目里面尝试把九宫格图片分别作为九个UIImageView来处理(而非一个StackView)。这次我新建了一个项目,来尝试这种情况。
依然是九宫格格子长宽 75px/75px,单张大图长宽 200px/200px。
效果如下图。用了一些不同的颜色让各个 view 更明显。因为我用的图片背景都是白色,所以我把单张大图右移了一些以示区分。右边那一块白色就是单张大图。(上下两块区域的文字位置没调好,但这不是重点:D)
相同的高度?一看图就能发现,单张大图和九宫格是一样高的。
我用print(onePic.frame.height)单张大图高度打印下来看,结果是 200.0。没有问题。
难道是九宫格变小了?print(firstImg.frame.height)结果是 75.0。也没问题。
打印没成功,于是我测量了一下截图中九宫格和单张大图的高度,结果两者都是 233px。这说明单张大图被拉伸了。
然后我突然想起print(onePic.image.size.height),打印出来结果是 233.0。图片果然被拉伸了。
之后我又检查了一下上次的截图,发现上次的单张大图一样被拉伸到九宫格的高度。
原因:
这次的模拟是重现上次的解决方案,只是将StackView换成了 9 个独立的UIImageView。
还是保持了底部的 button panel 与 onePic 和九宫格的间距都是 8px。(这次因为是分离的九个UIImageView,所以设置的是 button panel 和第九章图片的距离为 8px, ninethPic)
问题应该就是出在这里。当 button panel 与 onePic 之间存在这个 8px 的约束时,AutoLayout忽略了设定在 onePic 上固定高宽 200px 的约束,拉伸图片,使它满足和 button panel 的间距为 8px。
hidden 只是隐身、不可见,不是完全消失因为我也是刚接触 AutoLayout 不久,所以不清楚这样的情况是不是在文档里面已经写明了,还是这只是一个实际中发生的情况需要我们以后注意。
上一篇文章最后一部分是:九宫格图片数量变化时手动适应高度。
当时觉得是因为我用的StackView才导致隐藏下两排格子之后整个 view 的高度没有改变。现在我觉得我错了。
真正的原因应该是,hidden 只是隐身、不可见,不是完全消失。这意味着,虽然设置了图片为hidden,但其实它还是在那里占位的。所以整个 cell 里面的各种约束、子视图间的相对位置不会改变。
那怎么让九宫格的高度在格子隐藏之后变小,使得底下的 button panel 可以向上自适应呢?
第一个办法是上一篇文章中提到的通过修改constraint.constant。
另一个办法我们下面来说。
constraint priority为了让隐藏的 view 彻底消失,我赶紧 google 一下。
在这个问题(《AutoLayout with hidden UIViews?》)的回答中找到了有趣的 constraint priority。
被采纳的答案用的是提到过的第一个办法。
得票第二的回答提到了另一种办法。
The solution of using a constant 0 when hidden and another constant if you show it again is functional, but it is unsatisfying if your content has a flexible size. You"d need to measure your flexible content and set a constant back. This feels wrong, and has issues if content changes size because of server or UI events.
I have a better solution.
The idea is to set the a 0 height rule to have high priority when we hide the element so that it takes up no autolayout space.
他提到如果你的内容大小是可变化的,那么修改constraints.constant会很麻烦。这一点我很赞同。
而更好的办法就是设置 constraint priority。
官方文档:
NSLayoutConstraint
UILayoutPriorityRequired
简单来说,你可以给约束设置优先级,它的值在 0 - 1000 之间,优先极高的会先被满足。
比如拿我现在这个例子来说,现在有 button panel - onePic 和 button panel - ninethPic 两个 8px 间距的约束,分别对应的IBOutlet是bpAndOnePic以及bpAndNinethPic。假如我们如下设置:
bpAndOnePic.priority = 1000 bpAndNinethPic.priority = 250
那么AutoLayout会优先满足 button panel 和 onePic 之间的约束,效果如图:
可以看到 button panel 跑到上面去了。单张大图大小正常了。
实现自动向上适应九宫格的九张图片对应的IBOutlet分别为 firstPic、secondPic、thirdPic、fourthPic…ninethPic;单张大图为 onePic;底部 button panel 为 buttonPanel。
添加 buttonPanel 分别和 onePic、firstPic、fourthPic 以及 seventhPic 之间的 8px 上边距约束。
bpAndOnePic 是 button panel 和单张大图之间的约束;bpAndFirstPic 是 button panel 和九宫格第一张图之间的约束,bpAndFourthPic.priority 和 bpAndSeventhPic.priority 与之类似。(因为是九宫格,所以高度由每排第一张图存不存在决定。)
有了 constraint priority,我们可以这样设置:
bpAndOnePic.priority = firstPic.hidden ? 1000 : 250 bpAndFirstPic.priority = fourthPic.hidden && seventhPic.hidden && !firstPic.hidden ? 1000 : 250 bpAndFourthPic.priority = !fourthPic.hidden && seventhPic.hidden ? 1000 : 250 bpAndSeventhPic.priority = !seventhPic.hidden ? 1000 : 250
情况分析
如果九宫格第一排第一张图片隐藏了,说明现在是在展示单张大图(微博没有附加图片的情况我们在这里不考虑)。这时bpAndOnePic.priority等于 1000,而bpAndSeventhPic.priority,bpAndFourthPic.priority,bpAndFirstPic.priority都等于 250。bpAndOnePic.priority优先级最高,所以如下图:
如果只有第三排的三张图片隐藏,那么bpAndOnePic.priority、bpAndSeventhPic.priority和bpAndFirstPic.priority等于 250,而bpAndFourthPic.priority等于 1000。bpAndFourthPic.priority优先级最高,如下图:
其他情况在此不一一列举。
这样既解决了单张大图被拉伸的问题,又实现了九宫格图片数量变化时候的向上适应。
待解决:多余的空白部分怎么办?可以从上面的截图上看到,当内容变化的时候,cell 的高度并没有变化,所以下方有空白。
之前模仿微博客户端的项目中,我用了:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension }
它帮我自动去除了空白部分。
我尝试加上这两个函数在这个项目中,结果是:
所以下一步我会去搞清楚这个自动计算重新设置高度具体是怎么回事,解决掉多余的空白部分。
(另外,我感觉这跟我之前的项目 cell 里包含了 textField 有关 = =)
为很丑的例子 ui 道歉 = =
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/16168.html
摘要:二为啥我要用随着寸寸在市面同时使用越来越多,以及即将上市的,不同尺寸不同分辨率的设备将会越来越多,使用传统布局的工作量必将越来越大加上苹果发出的信号,使用势在必行。再看看苹果的态度,默认就是选择了使用。 这篇不是autolayout教程,只是autolayout动员文章和经验之谈,在本文第五节友情链接和推荐中,我将附上足够大家熟练使用autolayout的教程。这篇文章两个月前就想写下...
摘要:九宫格每张图的大小是,上下左右有的间距,所以总长宽为。九宫格的九张图片因为排布整齐,所以我直接用的一个。当我们要显示单张大图的时候,通过代码隐藏九宫格。如图九宫格图片数量变化时手动适应高度九宫格图片数量不够时,当然是通过隐藏多余的格子。 原文链接:AutoLayout:UITableViewCell 自适应高度的一个例子 目的 我在模拟微博客户端。 要实现:当一条微博包含 2-9 张图...
摘要:先在中取消勾选选项在自定义的大小和位置栏目中,对中的线全部去掉,这样就可以自适应各种尺寸大小的屏幕了。取消连线取消之后的结果可以看出,如果横屏,里边的块也处于中间位置。 一、简介 在以前的iOS程序中,是如何设置布局UI界面的?经常编写大量的坐标计算代码为了保证在3.5 inch和4.0 inch屏幕上都能有完美的UI界面效果,有时还需要分别为2种屏幕编写不同的坐标计算代码(即传说中的...
摘要:简介自动布局功能随着的发布横空出世,现在已经成为了机型适配最佳的解决方案之一。由于自动布局的特点,对于使用自动布局功能的视图,我们不能再像之前一样去操作它的等属性,我们通过对布局约束的操作来代替之前的方法来实现动画。 简介 AutoLayout自动布局功能随着iOS6的发布横空出世,现在已经成为了iOS机型适配最佳的解决方案之一。由于自动布局的特点,对于使用自动布局功能的视图,我们不能...
介绍 之前的几节中,我们都是通过修改一个约束的值来实现动画的。但是如果你想做的更多,你可能需要删除旧的约束并添加新的约束 删除约束 在IB中,我们可以为每一个约束注册一个identifiershowImg(https://segmentfault.com/img/bVqExV);showImg(https://segmentfault.com/img/bVqExY);showImg(https:/...
阅读 2726·2021-11-24 09:39
阅读 970·2021-11-18 10:02
阅读 732·2021-11-12 10:35
阅读 2523·2021-09-29 09:34
阅读 3341·2021-09-24 10:23
阅读 1489·2021-09-22 15:41
阅读 1501·2019-08-30 15:55
阅读 3416·2019-08-30 13:58