iOS,scrollView内容大小的高度等于内容视图';s高度,但仍可以垂直滚动?

iOS,scrollView内容大小的高度等于内容视图';s高度,但仍可以垂直滚动?,ios,uiscrollview,autolayout,masonry-ios-osx,Ios,Uiscrollview,Autolayout,Masonry Ios Osx,self是一个自定义视图。 我像这样设置约束。我做错什么了吗?谢谢 底线,如果您明确定义了内容视图和滚动视图之间的约束(将根据定义contentSize),然后明确定义了内容视图及其子视图之间的约束,那么,是,它将正确定义滚动视图的contentSize的大小 我建议使用视图调试器,并查看右侧面板中的约束: 在特定的屏幕快照中,我选择了滚动视图中内容视图中的第三个子视图(深蓝色),它告诉我们活动约束是: 从容器前缘偏移10(绿色) 从容器后缘偏移10(绿色) 从上面的子视图偏移10(深红色)

self是一个自定义视图。
我像这样设置约束。我做错什么了吗?谢谢

底线,如果您明确定义了内容视图和滚动视图之间的约束(将根据定义
contentSize
),然后明确定义了内容视图及其子视图之间的约束,那么,是,它将正确定义滚动视图的
contentSize
的大小

我建议使用视图调试器,并查看右侧面板中的约束:

在特定的屏幕快照中,我选择了滚动视图中内容视图中的第三个子视图(深蓝色),它告诉我们活动约束是:

  • 从容器前缘偏移10(绿色)
  • 从容器后缘偏移10(绿色)
  • 从上面的子视图偏移10(深红色)
  • 固定高度为200(我这样做是因为它没有隐含高度)
  • 主视图的宽度(鲜红色)小于20(这样它就占据了适当的水平空间,同样是因为没有隐含的宽度)
  • 从下面的子视图偏移10(浅蓝色)
因此,只需单击各个子视图和容器,并确认约束正是您想要的。很容易错过一个约束和/或无法激活一个约束,整个过程就会崩溃

顺便说一句,有时约束在哪些视图之间并不明显,但如果您点击约束按钮,当选择视图时,它将仅高亮显示具有约束的视图(在本例中,是内容视图、上下子视图和主视图;因为滚动视图(黄色)都不存在)第一个子视图(紫色)对第三个子视图也没有任何约束,因此您只能看到它们的线框,而不是内容):


请注意,这是一个示例,我想我会向您展示我使用的约束,以便auto layout能够基于内容视图和子视图正确计算
contentSize
,并具有完全满足且明确的约束:

[_contentView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.mas_equalTo(_scrollTabs);
    make.height.mas_equalTo(_scrollTabs);
}];

[_scrollTabs mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.mas_equalTo(self);
}];
let contentView=contentView()
contentView.translatesAutoResizezingMaskintoConstraints=false
contentView.backgroundColor=randomColor()
scrollView.addSubview(contentView)
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo:scrollView.topAnchor),
contentView.bottomAnchor.constraint(等式:scrollView.bottomAnchor),
contentView.leadingAnchor.constraint(等式:scrollView.leadingAnchor),
contentView.trailingAnchor.constraint(等式:scrollView.trailingAnchor)
])
var-previousView:UIView?
对于0中的uu..<4{
让子视图=SomeSubview()
subview.translatesAutoResizezingMaskintoConstraints=false
subview.backgroundColor=self.randomColor()
contentView.addSubview(子视图)
NSLayoutConstraint.activate([
子视图.leadingAnchor.constraint(等式:contentView.leadingAnchor,常量:10),
子视图.trailingAnchor.constraint(等式:contentView.trailingAnchor,常数:-10),
子视图.widthAnchor.constraint(等式:view.widthAnchor,常数:-20),
子视图.heightAnchor.constraint(equalToConstant:200)
])
如果以前的视图!=无{
subview.topAnchor.constraint(equalTo:previousView!.bottomAnchor,常量:10)。isActive=true
}否则{
subview.topAnchor.constraint(equalTo:contentView.topAnchor,常量:10)。isActive=true
}
previousView=子视图
}
previousView?.bottomAnchor.constraint(等式:contentView.bottomAnchor,常数:-10)。isActive=true

在您的示例中,让我感到奇怪的是,您同时设置了
(我假设设置了顶部、底部、前导和尾随约束)和
高度
。不需要设置内容视图的高度。你可以只定义边,你应该很好。高度由其子视图的约束决定

如果子视图似乎布局正确,但滚动视图的
contentSize
设置不正确,则罪魁祸首可能是最后一个子视图和内容视图之间缺少底部约束


如果你仍然有问题,我建议你为你的问题创建一个新的解决方案。您共享的代码不足。但我们也不希望看到您的所有代码或特定的UI。相反,创建一个独立的简化示例来说明您描述的问题。只有我们能够重现您的问题,我们才能帮助您解决问题。

底线是,如果您明确定义内容视图和滚动视图之间的约束(将根据定义
contentSize
),然后明确定义内容视图及其子视图之间的约束,那么,是,它将正确定义滚动视图的
contentSize
的大小

我建议使用视图调试器,并查看右侧面板中的约束:

在特定的屏幕快照中,我选择了滚动视图中内容视图中的第三个子视图(深蓝色),它告诉我们活动约束是:

  • 从容器前缘偏移10(绿色)
  • 从容器后缘偏移10(绿色)
  • 从上面的子视图偏移10(深红色)
  • 固定高度为200(我这样做是因为它没有隐含高度)
  • 主视图的宽度(鲜红色)小于20(这样它就占据了适当的水平空间,同样是因为没有隐含的宽度)
  • 从下面的子视图偏移10(浅蓝色)
因此,只需单击各个子视图和容器,并确认约束正是您想要的
let contentView = ContentView()
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.backgroundColor = randomColor()
scrollView.addSubview(contentView)

NSLayoutConstraint.activate([
    contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
    contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
    contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
    contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor)
])

var previousView: UIView?

for _ in 0 ..< 4 {
    let subview = SomeSubview()
    subview.translatesAutoresizingMaskIntoConstraints = false
    subview.backgroundColor = self.randomColor()
    contentView.addSubview(subview)

    NSLayoutConstraint.activate([
        subview.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
        subview.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
        subview.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -20),
        subview.heightAnchor.constraint(equalToConstant: 200)
    ])

    if previousView != nil {
        subview.topAnchor.constraint(equalTo: previousView!.bottomAnchor, constant: 10).isActive = true
    } else {
        subview.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
    }

    previousView = subview
}

previousView?.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10).isActive = true