UIScrollView 中的 UIView 尊重一些约束,但不尊重其他约束

Posted

技术标签:

【中文标题】UIScrollView 中的 UIView 尊重一些约束,但不尊重其他约束【英文标题】:UIView in UIScrollView respects some constraints but not other 【发布时间】:2018-08-24 04:00:28 【问题描述】:

我需要在UIScrollView中添加一个containerView,然后在containerView中添加多个子视图。出于某种原因,containerView 不遵守 top/bottom/left/rightAnchor 约束,但它适用于 width/height/centerX/centerYAnchor

注意:如果超级视图是UIView 而不是UIScrollView,它可以正常工作。

该项目是 100% 基于代码的。使用 Swift 4.1 和 Xcode 9.4

这不起作用

containerView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0).isActive = true
containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0).isActive = true
containerView.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 0).isActive = true
containerView.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: 0).isActive = true

这行得通

containerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
containerView.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true
containerView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
containerView.centerYAnchor.constraint(equalTo: scrollView.centerYAnchor).isActive = true

在这两种情况下,scrollView.constraints 数组总共包含 4 个约束。

有趣的是它们的打印输出是不同的。一些不起作用的约束(.top 和 .left)是使用 Autolayout Visual Format Language 打印的。另外,请注意第三个中的 (LTR):

ScrollView [
<NSLayoutConstraint:V:|-(0)-[UIView] (active, names: '|':UIScrollView:)>,
<NSLayoutConstraint:UIView.bottom == UIScrollView.bottom (active)>,
<NSLayoutConstraint:H:|-(0)-[UIView](LTR) (active, names: '|':UIScrollView:)>,
<NSLayoutConstraint:UIView.right == UIScrollView.right (active)>]

有效的约束打印如下:

ScrollView [
<NSLayoutConstraint:UIView.width == UIScrollView.width (active)>,
<NSLayoutConstraint:UIView.height == UIScrollView.height (active)>, 
<NSLayoutConstraint:UIView.centerX == UIScrollView.centerX (active)>, 
<NSLayoutConstraint:UIView.centerY == UIScrollView.centerY (active)>]

我研究了 *** 并发现了几个问题,例如 this,但它们并没有真正帮助我解释问题是什么(或 UIScrollView 对约束的要求)。

有什么想法吗?

【问题讨论】:

【参考方案1】:

UIScrollView 需要滚动其中的一些内容。您添加的视图(在滚动视图内)没有大小(高度和宽度),因此滚动视图无法识别其内容的大小。

为视图添加大小(在滚动视图内),它会起作用。

containerView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0).isActive = true
containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0).isActive = true
containerView.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 0).isActive = true
containerView.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: 0).isActive = true
// Size constraints
containerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
containerView.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true

// To check scrolling of container view; try this
containerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor + 50.0).isActive = true
containerView.heightAnchor.constraint(equalTo: scrollView.heightAnchor + 50.0).isActive = true

【讨论】:

谢谢@Krual。现在我明白了为什么 UIScrollView 需要大小。尽管 Autolayout 的整个想法是,如果你定义了 4 个锚点,则应该推断出大小(考虑到 superview 的大小)。或者如果我定义了 containerView 的大小,我只需要 2 个锚点(即 .top/.left)来定义视图的几何形状。还。如果我将 contentSize 设置为固定值,则它不起作用... Thx.... e【参考方案2】:

这是因为UIScrollView 需要以某种方式设置它的contentSize。通过将UIView 的布局锚定到UIScrollView 的两侧,自动布局仍然无法明确知道contentSizeUIScrollView 是什么。

由于UIScrollView 可能锚定到某个父视图,UIScrollView 的高度和宽度已经定义。通过给UIView这些约束,自动布局可以确定UIView的大小,然后使用该大小来设置contentSizeUIScrollView

【讨论】:

【参考方案3】:
Go through the following points in order to use scrollview in your application. 
 1. First add UIScrollview and give it constrain in view(left, right,width,height).[![enter image description here][1]][1]
 2. Now each scrollview has content view which should be there , we cannot add our required views directly to UIScrollview.
 3. Add view to scrollview(we name it content view) , give it top,bottom, left and right constrain. Apart from these we need to add height and width constrain to the content view. 
 4. If you want to have vertical scrollview then give width equal to scrollview and a proper height (like height constrain = 600)or greater than scrollview height.
 5. If you want to have horizontal scrollview then give height equal to scrollview and width greater than actual width of scrollview.

看看下面添加的内容视图的约束

【讨论】:

现在您应该在添加为滚动视图子视图的视图中添加自定义视图。 嗨@Himan。您能否指出关于不向 UIScrollView 添加多个子视图的参考? Apple 的文档将滚动视图称为“内容视图”。我能够向滚动视图添加具有不同锚点的多个子视图。

以上是关于UIScrollView 中的 UIView 尊重一些约束,但不尊重其他约束的主要内容,如果未能解决你的问题,请参考以下文章

如果其他 UIView 带有隐藏选项,如何使下 UIView 固定到 UIScrollView 中的上 UIView?

UIScrollview 中的 UIView 中的 UITableView :点击时 UITableView 数据被清除

自定义 UIView 中的 UIScrollView 不滚动

UIScrollView中的UIView不出现

在 UIScrollview 中的 UIView 上的屏幕中的框架

在uiscrollview中的多个uiview之间传递数据