ScrollView的contentOffset和contentInset是什么?

42

关于ScrollView,我有两个问题。第一个是我的主要问题,另一个是次要的困惑。

1.ScrollViewcontentOffsetcontentInset到底是什么?我会在下面给出更多细节。

2.我创建了一个ScrollView,但似乎ScrollView无法在任何方向上滚动。这个问题是关于offset还是inset?我会在下面给出更多细节。

问题1的细节:

有时候,contentOffset属性和contentInset属性似乎有很大的区别,但是当我尝试实现一些与这两个属性相关的功能时,我感到困惑。 我在这里做了一个简单的说明图。你能帮我弄清楚哪部分是offset,哪部分是inset吗?

enter image description here

问题2的细节:

我使用以下函数添加一个ScrollView

 func addScrollView(){
            // assign a new ScrollView to "scroll" class member 
            scroll = UIScrollView(frame: CGRectZero)
            scroll!.translatesAutoresizingMaskIntoConstraints = false
            // change it to gray color to help recognising 
            scroll!.backgroundColor = UIColor.grayColor()
            self.view.addSubview(scroll!)

            //add some constraints,[you can neglect following part]
            let x = NSLayoutConstraint(item: scroll!, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)
            self.view.addConstraint(x)

            let y = NSLayoutConstraint(item: scroll!, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1/2, constant: 25)
            self.view.addConstraint(y)

            let left = NSLayoutConstraint(item: scroll!, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1, constant: 10)
            self.view.addConstraint(left)

            let upperSpacing = NSLayoutConstraint(item: scroll!, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 50)
            self.view.addConstraint(upperSpacing)

            let w = NSLayoutConstraint(item: scroll!, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.GreaterThanOrEqual, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0, constant: 10)
            self.view.addConstraint(w)

            let h = NSLayoutConstraint(item: scroll!, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: scroll!, attribute: NSLayoutAttribute.Width, multiplier: 1, constant: 0)
            self.view.addConstraint(h)
            print("add scroll view Successed")
        }

它不能滚动,只能容纳一些东西(按钮或文本字段等)来填充其大小,而不是将更多东西放在我们看不到的地方。

那么问题是否与设置 outset 和 inset 有关?我该如何设置才能解决这个问题?如果这样做,我如何通过编程向未显示的位置添加东西(按钮等)?

希望您能告诉我一些信息!

3个回答

71

几点观察:

  • contentOffset 是用户当前在滚动视图中滚动的位置。这个显然随着用户的滚动而改变。通常情况下,您不会通过编程方式更改它(除非您想要程序化地滚动到某个位置,例如有一个按钮可以滚动到顶部)。

  • contentInset 是内容在滚动视图中视觉上嵌入的量(即滚动视图内的“边距”是多少)。您通常在IB(Interface Builder)或 viewDidLoad 中设置一次,因为滚动视图在实例化时就已经确定了。

  • contentSize 是可滚动内容的大小。请注意,在使用自动布局时,您不必手动指定此值,而是通过您在滚动视图及其子视图之间指定的约束(以及子视图和子视图之间的约束)计算出来的。

为了使滚动正常工作,需要综合考虑以下两个因素:(a)滚动视图的 bounds,减去任何 contentInset;以及(b)从子视图的约束条件自动计算得出的 contentSize


嗨,罗布!谢谢你!我可以理解前两个问题。但是为了简化第三个问题,我想确认一下,“可滚动内容”是否仅指scrollView的大小? - Microos
1
不,我所说的“可滚动内容”是指滚动视图的所有子视图。如果所有这些子视图的约束都已完全定义,则滚动视图的contentSize将被计算并设置。因此,假设您的滚动视图高度为480个点,但其所有子视图及其间距的高度(由约束规定)总共为700个点(contentSize.height为700),则您将能够在480个点的滚动视图内上下滚动那700个点的内容。 - Rob

11

contentOffset 表示滚动视图内容相对于左上角的原始坐标的当前位置。除非您想要以编程方式调整滚动位置,否则不应该程序化地设置此值。

contentInset 允许在滚动视图中指定内容周围的边距。您可以通过以下方式以编程方式指定边距:

scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 7.0)

1
你好!Eneko Alonso!首先感谢您的回答!我想问一下,编程上设置插图是为了让用户查看内容时有一个较小的区域。我的理解正确吗? - Microos
@Microos,好问题。如果我们也知道答案就太棒了! - Revanth Kausikan
@Microos,正确的做法是将contentInset设置为大于零的值,这样会在内容视图周围添加“填充”。例如,在您希望内容与屏幕边缘有一些合并的情况下,可以将左右插入设置为10-20像素。 - Eneko Alonso

0

虽然这个问题比较老,但是针对你的第二个问题,你应该使用contentSize而不是offset和inset。

  let contentWidth = 400 //or any other value that suits you
  let contentHeight = 50 
  scrollView.contentSize = CGSize(width: contentWidth, height: contentHeight)

如果内容小于任一维度,则会根据比例垂直或水平滚动。

敬礼


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接