【问题标题】:Calculating contentSize for UIScrollView when using Auto Layout使用自动布局时计算 UIScrollView 的 contentSize
【发布时间】:2016-12-21 07:03:38
【问题描述】:

这是一个关于某些有效但可以写得更好的快速问题。我有一个UIScrollView 和一个放置在里面的对象列表,一个在另一个之下。一切都在viewDidLoad() 期间完成,对象的放置使用Auto Layout。这是我将UIScrollViewcontentSize 高度设置为适当值的方法。

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    globalView.contentSize = CGSize(width: globalView.frame.width,
                                    height: globalView.frame.height * 1.59)
}

它有效,但任意值 1.59 显然是由我尝试了一些可能的值决定的。 在这种情况下计算 contentSize 的正确方法是什么?我正在以编程方式进行所有操作。 在网上搜索并没有让我得到任何简单而明确的答案,所以即使这可能是一个有些重复的问题,我还是决定重新表述它。

【问题讨论】:

  • 您可以在同一主题上找到很多关于将约束设置为 UIScrollView 的答案。如果您将约束正确设置到 UIScrollView 内的所有组件,那么您不需要以编程方式设置常量大小。请参阅此链接解释相同 - stackoverflow.com/questions/35624873/…
  • 没错,但他们中的大多数(全部)都认为您正在使用情节提要:)
  • 如果您从代码中添加子视图,您可能只需转到 Size Inspector 并在底部选择 Ambiguity->Never Verify。
  • @Paweł Pela :这是不久前的事了,但无论如何,如果您有兴趣,请查看我最喜欢的解决方案。在以下答案之一中查找 AutoLayScroll。

标签: ios swift uiscrollview autolayout


【解决方案1】:

以编程方式指定内容大小不是好方法。以下解决方案将 使用自动布局工作,根本不需要设置内容大小。它将根据 添加了多少 UI 字段来查看。

第 1 步:

添加滚动视图以在情节提要中查看并添加前导、尾随、顶部和底部约束 (所有值都为零)。

第 2 步:

不要直接在scrollview上直接添加你需要的view,先添加一个view 滚动视图(这将是我们所有 UI 元素的内容视图)。 将以下约束添加到此视图。

1) 前导、尾随、顶部和底部约束 (所有值都为零)。

2) 向主视图(即包含滚动视图)添加等高、等宽。 对于相等的高度,将优先级设置为低。 (这是设置内容大小的重要步骤).

3) 此内容视图的高度将根据添加到视图中的视图数量而定。 假设你添加最后一个视图是一个标签,他的 Y 位置是 420 和高度 是 20,那么您的内容视图将是 440。

第 3 步:根据您的要求为您在内容视图中添加的所有视图添加约束。

供参考:

我希望这对你有帮助。

【讨论】:

  • 这听起来很有趣,但因为我没有使用故事板。在以编程方式工作时,我需要了解如何应用这些解释。第一个问题是,在第 2 步中,如何将视图设置为内容视图?
  • 它的正常视图,我已添加到滚动视图(视为 contentView)。然后在那个视图上我放置所有 UI 元素。
  • 我终于做到了,它以我想要的方式以编程方式工作。但我仍然不确定这个 contentview 的东西是如何工作的。如果我添加 3 个不同高度的子视图会怎样?哪一个将被视为内容视图?
  • 太棒了!如果您想将 3 个视图添加到滚动视图中,那么我所做的就是获取一个视图(其中将包含 3 个视图)并将其添加到滚动视图中。而已。 (我在上面的例子中提到过)
  • 这是迄今为止我看到的关于这个主题的最佳答案!但还有另一种情况:如果我的视图高度 + 边距的总和小于可用空间,则等高约束获胜,因此,当键盘弹出并且我将插图设置为键盘的高度时,我可以向下滚动太多了。如何解决这种情况?
【解决方案2】:

虽然我终于解决了这个问题并使事情顺利进行。 我注意到我在网上能找到的所有相关答案都是针对故事板用户的。但是没有什么可以通过编程来实现的。

所以我决定制作一个非常简单的演示应用程序来展示如何实现这一点。我希望它在某些时候对某人有用。

这是在 GitHub 上获取它的地址: https://github.com/zaxonus/AutoLayScroll

【讨论】:

  • 创建此示例是为了展示如何以编程方式完成所有操作。如果你想使用 XIB(故事板),网上有很多例子。第一个是上面提到的,在接受的答案中。
  • 这太棒了。几天的尝试,这是唯一有效的。注意,在 Swift 3 中工作,给定变量重命名。谢谢先生。
  • 我认为您可以使用在各个方向上固定到UIScrollViewUIStackView 来代替。
【解决方案3】:

我还以编程方式使用约束来动态修改 UIScrollView 的 contentSize 。我几乎按照 Shrikant 的说明进行操作,但是对于步骤 2.1,我将 centerX 设置为 scrollViews.centerX 而不是设置前导边距和尾随边距(不知道为什么前者有效,而后者无效)。然后作为最后一步,在添加最终子视图后,我做了以下操作:

contentView.layoutIfNeeded() //set a frame based on constraints
scrollView.contentSize = CGSize(width: contentView.frame.width, height: contentView.frame.height)

希望这对将来的某人有所帮助。

【讨论】:

    【解决方案4】:

    您需要做的就是确保第一个子视图的顶部锚点被约束到滚动视图的顶部锚点,而最后一个子视图的底部锚点被约束到滚动视图的底部锚点

    【讨论】:

      【解决方案5】:

      如果您不想使用故事板,而只使用约束,您可以按照此处的指南进行操作

      https://redflowerinc.com/implement-uiscrollview-using-constraints-no-need-to-use-content-size/

      使用可以使用底部锚点并将您的视图固定到滚动视图。通过使用约束,您不需要使用内容大小。

      【讨论】:

      • 这正是使用约束实现 ScrollView 所需要的!关键代码是“lastLabel.bottomAnchor.constraint(equalTo: scrollview.bottomAnchor).isActive = true”
      【解决方案6】:

      这是来自 Apple 的官方指南,对我有用。

      https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html

      为了支持滚动视图,系统对约束的解释不同,具体取决于约束所在的位置。

      • 滚动视图和滚动视图之外的对象之间的任何约束都附加到滚动视图的框架上,就像任何其他视图一样。
      • 对于滚动视图及其内容之间的约束,行为会因受约束的属性而异:
        • 滚动视图的边缘或边距与其内容附加到滚动视图的内容区域之间的约束。
        • 高度、宽度或中心之间的约束附加到滚动视图的框架。
      • 您还可以在滚动视图的内容和滚动视图之外的对象之间使用约束来为滚动视图的内容提供固定位置,使该内容看起来漂浮在滚动视图之上。

      对于大多数常见的布局任务,如果您使用虚拟视图或布局组来包含滚动视图的内容,逻辑会变得容易得多。在 Interface Builder 中工作时,一般做法如下所示:

      1. 将滚动视图添加到场景中。
      2. 像往常一样绘制约束来定义滚动视图的大小和位置。
      3. 向滚动视图添加视图。将视图的 Xcode 特定标签设置为 Content View。
      4. 将内容视图的顶部、底部、前导和后沿固定到滚动视图的相应边缘。内容视图现在定义了滚动视图的内容区域。

      此时内容视图没有固定大小。它可以拉伸和增长以适应您放置在其中的任何视图和控件。

      1. (可选)要禁用水平滚动,请将内容视图的宽度设置为等于滚动视图的宽度。内容视图现在水平填充滚动视图。
      2. (可选)要禁用垂直滚动,请将内容视图的高度设置为等于滚动视图的高度。内容视图现在水平填充滚动视图。
      3. 在内容视图中布置滚动视图的内容。使用约束在内容视图中正常定位内容。

      重要

      您的布局必须完全定义内容视图的大小(第 5 步和第 6 步中定义的除外)。要根据内容的固有大小设置高度,您必须有一个完整的约束链和从内容视图的顶部边缘延伸到其底部边缘的视图。同样,要设置宽度,您必须拥有从内容视图的前缘到其后缘的不间断的约束和视图链。

      如果您的内容没有固有的内容大小,则必须向内容视图或内容添加适当的大小约束。

      当内容视图高于滚动视图时,滚动视图启用垂直滚动。当内容视图比滚动视图宽时,滚动视图启用水平滚动。否则,默认禁用滚动。

      【讨论】:

        猜你喜欢
        • 2014-12-29
        • 2013-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-25
        • 1970-01-01
        • 2012-12-11
        相关资源
        最近更新 更多