UIScrollView 如何改变框架,但不改变边界? UIScrollView 是如何工作的?

Posted

技术标签:

【中文标题】UIScrollView 如何改变框架,但不改变边界? UIScrollView 是如何工作的?【英文标题】:How does UIScrollView change the frame, but not the bounds? How does UIScrollView work? 【发布时间】:2014-02-11 00:34:37 【问题描述】:

我理解框架和边界之间的区别,我认为边界是视图的本地坐标系,而框架是超级视图。

但是,对于滚动视图,我有点困惑。

当我在 UIScrollView 中有一个 UIImageView 并捏放大它时,似乎框架变大(宽度和高度)也会增加相应 UIImage 的宽度和高度。

但是,UIImageView 的边界似乎根本没有改变。

这是为什么?滚动视图在所有这些方面是如何工作的?我已经阅读了多个问题并检查了文档,但这个解释让我难以理解。

放大 UIScrollView 如何影响其内容?它只是改变了缩放视图的框架,但不知何故没有改变边界?

【问题讨论】:

框架不变,边界也不变。滚动视图调整其内容视图的转换。 【参考方案1】:

见解释in my book:

滚动视图通过对可缩放视图应用缩放变换来缩放;因此,可缩放视图的框架也被缩放。此外,滚动视图关注的是让滚动继续正常工作:用户滚动时的限制应该继续匹配内容的限制,并且像 scrollRectToVisible:animated: 这样的命令应该继续以相同的方式为相同的值工作。因此,滚动视图会自动缩放自己的 contentSize 以匹配当前的 zoomScale。 (实际上,您可以通过在 UIScrollView 子类中覆盖 setContentSize 来检测这种情况:您可以看到滚动视图在缩放时调整其自己的内容大小。)

基本上(尽管从上面的引用中不太清楚)我们与可伸缩视图的框架无关 - 或 任何 视图 - 应用了非身份转换它,这正是这里的情况。 Apple 关于 UIView 的文档非常清楚地说明了这一事实。因此,您不应该查看框架 - 只有变换。您正在读取的帧 更改纯粹是转换更改的副作用。

至于可伸缩视图的边界——显然边界不会改变;这就是转换如何工作的重点。它保持一个常量centerbounds,因此尽管进行了变换,但子视图和绘图仍然可以在参考系坐标内正确运行。我的书talks you through对此也有理解。

另一方面,滚动视图自身的边界当然可以改变它们的原点,尤其是因为这与滚动视图滚动的含义完全相同。滚动边界原点的改变,简单明了。这在缩放过程中也不足为奇,因为正如我刚才所说,内容大小发生了变化,因此可能会重新定位内容,以便在缩放时保持连贯地显示。

【讨论】:

最后一段,你指的是滚动视图的边界还是图像视图的边界?当我使用 Apple 的 PhotoScroller 演示并观察滚动视图的移动值时,此代码中未注释的行是唯一更改的行:i.imgur.com/QtWp85k.png 如您所概述的图像视图,但滚动视图的边界清晰放大和平移时发生变化,这会改变原点。 滚动就是。再次,请参阅我的书(我已经给了你一个链接)关于滚动视图的工作原理。它通过更改边界原点来工作 - 就像您对任何视图所做的那样,以“滚动”其子视图的位置。但是,您的问题是关于缩放,而不是滚动,所以我没有在回答中讨论这个问题。 编辑澄清(并显示缩放和二次滚动之间的联系)。

以上是关于UIScrollView 如何改变框架,但不改变边界? UIScrollView 是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView 神秘地改变框架和内容大小

自动布局正在改变 UIScrollView 的 contentOffset 旋转

在 UIScrollView 中调整视图大小后,滚动视图不知道它改变了

为啥 UIScrollView 会自动改变 contentOffset?

UIScrollView 捏放大到 CGContextStrokePath 而不改变线宽

目标 C:使用 UIScrollview 改变方向