使用Xib(Storyboard)布局UIScrollView - 以及解决has ambiguous scrollable content width/height问题

概要

在xib中自动布局UIScrollView一直都是个挺麻烦的事。尤其从Xcode11开始,苹果对UIScrollView引入了“Content Layout Guides”,这导致默认情况下使用之前的方式布局会遇到“has ambiguous scrollable content width/height”错误。下面分别介绍一下如何关闭“Content Layout Guides”并继续使用老版本的布局方法,以及如何使用新方法进行布局

解决has ambiguous scrollable content width/height问题

解决这个问题只需要关闭UIScrollView的“Content Layout Guides”功能即可,新版xcode默认会打开此功能,由于我们并没有对此功能进行设置,所以就导致了错误。关闭后,左侧视图结构中Scroll View下的两个属性也会自动消失,接下来就可以用你熟悉的老办法进行布局了。

 

关闭Content Layout Guides后,如何使用之前的方式布局

在Xib中布局UIScrollView,其实主要就是两件事:

1:为UIScrollView添加约束,确定UIScrollView的大小和位置。也就是确定显示窗口;

2:在UIScrollView中添加一个内容视图(想在UIScrollView中滚动的东西),为这个内容视图添加约束,确定内容的大小和位置。也就是确定可滚动的内容;

* 图片拍摄于2021.7 库布齐沙漠

具体步骤:

1:拖动一个UIScrollView到屏幕,关闭Content Layout Guides选项,然后为此UIScrollView添加约束;

给这个UIScrollView添加上下左右边距后,这个UIScrollView就有了完整的约束,此时滚动视图的显示窗口位置也就固定了。

2:接下来开始添加并设置滚动内容。

这里有一点需要注意,滚动视图的内容大小(contentSize),是通过其内部的子视图大小来计算的。一个滚动视图内,可以包含多个子视图,这些子视图共同组成的矩形区域,才是滚动视图的内容视图大小。这个区域包含外层边距以及中间空白的间距部分,如下图:

 

所以在设置内容视图的约束时,必须满足计算出完整内容大小的所有条件(边距+长宽)。注意此处设置内容视图边距时(例如上图中UIView1的顶边距10),实际上是在设置UIScrollView的内容视图大小,以及UIView1在整个内容区域中的偏移位置。

当内容区域长度(宽度)小于等于显示区域的长(宽)时,视图纵向(横向)不可滚动;

了解了内容视图的原理,实现就是一件很容易的事了,下面实现一个只包含一个内容视图,并且只能垂直滚动的例子。

首先拖动一个UIView(也可以是其他视图)到滚动视图中,然后为这个内容视图添加约束。

 由于此时并未给内容视图(UIView)添加宽度约束,所以滚动内容的宽度是无法计算的(只知道边距,不知道宽)。我们也可以直接给UIView设置一个固定的宽度,但是为了实现只能垂直滚动的效果,设置UIView宽度等于UIScrollView宽度,显然更加合理:

至此UIScrollView和内容的所有约束都添加好了,在xib中是可以直接预览滚动效果的(在滚动视图上滑动鼠标即可实现滚动), 添加后的约束情况如下图:

 

打开Content Layout Guides后,使用新方法进行布局

接下来研究一下Content Layout Guides。打开这个选先后,最明显的区别就是UIScrollView下面出现了两个新项目:

Content Layout guide - 用来设置滚动内容的大小;

Frame Layout Guide - 用来设置滚动视图窗口大小;

也就是说我们可以实现不依赖滚动视图的内容,来单独控制滚动区域了。

依然是制作一个只能上下滚动的demo。先拖动一个UIScrollView到视图中,然后设置UIScrollView的四边约束,设置四边约束后,UIScrollView的大小和位置(视图窗口)就确定了,也就是说新功能的第二项Frame Layout Guide不需要在进行任何设置了。

由于 Content Layout guide还没有设置,所以会提示如上错误。下面加入一个内容视图,并设置内容视图和Content Layout guide。

由于视图内容区域不再由内容视图计算,所以此处只需要设置内容视图(UIView)自己的宽度和高度即可,不需要在设置边距。设置高度:

 设置宽度仍然可以使用原来的方法,让UIView宽度等于UIScrollView宽度,当然也可以借助Frame Layout Guide,因为Frame Layout Guide就是UIScrollView的视图窗口,而且UIScrollView的frame已经确定了,所以我们只要让UIView宽度等于Frame Layout Guide的横向宽度就行了,这样显得更合理。设置方法如下:

 至此已经完成了内容UIView的宽高设置,也就是确定了内容的大小。接下来设置Content Layout guide,确定UIScrollView的滚动范围。让滚动范围等于UIView大小,同样是右键拖动UIView,到Content Layout guide上松开,然后按住Shift键选中四边对齐,设置方法如下:

以上设置使Content Layout guide(滚动范围)的上下左右分别对齐到UIView的上下左右。设置完成后,对齐偏移量会使用视图当前所在位置的值,需要手动修改一下,上下左右分别改为0,UIView与Frame Layout Guide的宽度比例改为1:

 设置完的所有约束如下:

现在可以在xib中预览了。 Content Layout Guides的主要区别就是通过专门的属性来设置内容视图,可以使用UIScrollView外面的视图来动态控制滚动视图内容的大小,这样之前某些必须通过代码完成的功能,现在xib中也可以实现了。

DEMO :  https://github.com/zcsoft/XibScrollViewDemo

Create a UIScrollView using Auto Layout in Storyboard

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值