【问题标题】:iOS, the height of scrollView content size is equal to the content view's height, but it can still scroll vertically?iOS,scrollView内容大小的高度等于内容视图的高度,但它仍然可以垂直滚动?
【发布时间】:2017-01-23 06:44:00
【问题描述】:
[_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);
}];

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

【问题讨论】:

  • 你想要达到什么目的?
  • @CodeChanger,我希望它只水平滚动,所以我为滚动视图(_scrollTabs)设置了一个内容视图,并使其高度等于滚动视图。我是否错过了一些限制以使其发挥作用?
  • @Rob,感谢您提供上述示例代码。我对带有滚动视图的自动布局有所了解。我正在尝试使用内容视图来保存我想在滚动视图中显示的所有子视图(_scrollTabs),并且我已将所有这些子视图的所有约束设置为_contentView。计算_scrollTabscontentSize够不够?
  • 您是说它滚动不正确(即您没有任何低于 44 的内容)还是您说它滚动绝对正确,但 contentSize 似乎不正确?如果是后者,您在什么时候暂停执行并查看contentSize?我假设您没有在viewDidLoad...中查看它...

标签: ios uiscrollview autolayout masonry-ios-osx


【解决方案1】:

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

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

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

  • 从容器前缘偏移 10(绿色)
  • 从容器后缘偏移 10(绿色)
  • 从上面的子视图偏移 10(深红色)
  • 固定高度为 200(我这样做是因为它没有隐式高度)
  • 主视图的宽度(亮红色)减去 20(以便它占据适当数量的水平空间,同样因为没有隐式宽度)
  • 从下面的子视图偏移 10(浅蓝色)

因此,您只需单击各种子视图和容器,并确认约束正是您想要的。很容易错过一个约束和/或无法激活一个约束,整个事情就崩溃了。

顺便说一下,有时它不明显是什么样的约束之间的视图,但如果您点击约束按钮,,则选择视图时,它将突出显示您有约束的视图(in这个例子,到内容视图,到上面和下面的子视图,以及主视图;因为滚动视图(黄色)和第一个子视图(紫色)都没有对第三个子视图有任何约束,所以你只看到它们的线-框架,而不是它们的内容):


注意,这是一个示例,我想我会向您展示我使用的约束,以便自动布局可以根据内容视图和具有完全满足、明确约束的子视图正确计算 contentSize

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

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

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

如果您仍然遇到问题,我建议您创建一个simplified, yet complete example 来处理您的问题。您共享的代码不足。但我们也不想看到您的所有代码或您的特定 UI。相反,创建一个独立的简化示例来显示您描述的问题。只有能够重现您的问题,我们才能帮助您解决问题。

【讨论】:

  • 感谢您的帮助!对不起,我的错误是对 Stackoverflow 的点头!最近将给出一个例子。正如你所建议的,我检查了视图调试器,然后打印了我的滚动视图的描述,上面写着Printing description of $63: &lt;UIScrollView: 0x625de00; frame = (0 0; 276 44); clipsToBounds = YES; gestureRecognizers = &lt;NSArray: 0x18171680&gt;; layer = &lt;CALayer: 0x14d676d0&gt;; contentOffset: {0, 0}; contentSize: {308.5, 44}&gt;。似乎contentSize 的高度等于frame 的高度。但它仍然可以垂直滚动。
  • 我知道现在发生了什么。我把滚动视图放在导航栏的正下方,忘记将automaticallyAdjustsScrollViewInsets 设置为NO。所以这个愚蠢的问题发生了......
猜你喜欢
  • 2022-06-11
  • 2019-04-06
  • 1970-01-01
  • 1970-01-01
  • 2019-03-28
  • 1970-01-01
  • 2017-12-07
  • 2013-02-20
  • 2012-02-10
相关资源
最近更新 更多