gpt4 book ai didi

ios - 没有明确的宽度约束和更大或相等的尾随空间行为不当的自动布局

转载 作者:可可西里 更新时间:2023-11-01 04:44:04 26 4
gpt4 key购买 nike

我有一个直接包含在 View Controller 的内容 View 中的 ScrollView ,在两个维度上都是全尺寸的。从 ScrollView 到其超 View (水平)和布局指南(垂直)的顶部、底部、前导和尾随空间约束都设置为 0。 VC 最终意味着作为 subview Controller 嵌套在一两个 View 中地方。我正在使用 Storyboard。

我在 ScrollView 中放置了许多元素并将它们约束到它,但我看到了各种奇怪的行为。下面是一个屏幕截图,其中选择了 ScrollView 的所有 subview 来显示它们的约束。 ScrollView 对顶级 View 的四个约束在其中不可见。 View Controller 已设置为 Freeform 大小,其顶级 View (以及相应的 ScrollView 的内容 View )高 616 pts,确保在运行时需要滚动。

Constraints visualized

在分析屏幕截图之前,这里列出了我想要实现的目标。

  • 元素之间的垂直间距由设计者设置并固定。 (顺便说一句,此线框中的垂直约束、文本样式等都不是最终的;整个图像仅用于说明目的。)
  • 所有标签(除了最上面的)应该从它们的内在尺寸开始,扩展到 ScrollView 的宽度(减去两侧 20 pts 的标准 HIG 水平空间)。
  • 按钮不太可能比这大得多,但在本地化意外的情况下,我们希望它们的行为就像标签一样。 (“另一个按钮”有一个额外的垂直 ≥ 约束;它与这个问题无关。)
  • web view的高度是固定的,宽度由scroll view的宽度决定;两侧的标准 20 pt 水平空间。
  • TextView 具有最小高度(此处为 67 pts),但如果包含的文本太大而无法容纳,它们应该垂直扩展。它们都不可编辑或滚动。与 Web View 一样,它们与前缘和后缘水平间隔标准 20 pts。

  • 如您所见,没有任何元素具有明确的宽度约束。整个事情依赖于元素和 ScrollView 之间的前导和尾随空间约束。在我看来,这种布局可以在不改变约束条件的情况下,在假设的 future 320 pt 宽的 iPhone 上正常工作。旋转到横向后它也可以工作(它可能看起来有点傻,但它会工作)。

    我将一步一步地完成这些要点,并在必要时引用屏幕截图。

    1:这有效,这里没有什么不寻常的。

    2:标签的前导约束都是简单的 20 pt 标准空间。尾随约束大于或等于 20 pt 标准,表面上允许它们增长为 scrollView.frame.size.width-40宽,但没有更宽。

    3: 2 .

    4 和 5:这就是有趣的地方。 web view 和 text view 都被列为 Misplaced Views,IB 说它们的框架在运行时会有所不同。表示正确帧的橙色虚线边框仅水平到达具有大于或等于尾随约束的最长元素;在这里,它是“带有长标题的按钮”,其右边缘是虚线边框边缘的结束位置。

    构建这组 View 及其约束,我预计会遇到一些麻烦。我知道让 UITextViews 垂直增长高于此处定义的 ≥ 67 高度会很棘手,也许只能通过代码实现。仅通过 IB 使标签和按钮按上面指定的方式工作似乎也有点不确定。

    我没想到的是,网络和 TextView 报告的正确框架仅与最宽的标签或按钮一样宽。似乎通过这种设置, ScrollView 实际上不会是 320 pts 宽,而只是适合最长元素及其间距所需的宽度,并且 web 和 TextView 应该符合要求。鉴于 ScrollView 在所有方面都被严格限制在顶层 View (设置为 320 pts 宽),我不知道为什么会这样。某些东西显然必须定义 ScrollView 的初始宽度,但是为什么我从 ScrollView 到顶级 View 所做的约束不这样做呢?

    鉴于这组 View 的上述规范,我需要更改什么才能实现它?

    这个案例表明我还没有真正正确地理解自动布局,我希望答案能够让我了解它的许多关键方面。

    最佳答案

    关于 Xcode 关于错位 View 的警告,在 Storyboard中选择 View Controller ,点击 Canvas 右下角的“解决自动布局问题”按钮(它看起来像星球大战中的 Tie Fighter),然后选择“更新 View Controller 中的所有帧”。这会强制您的所有 View 都反射(reflect)它们的约束。

    使用自动布局 UIScrollView是一种不同的动物;如此之多,以至于 Apple 认为有必要发布有关该问题的技术说明:https://developer.apple.com/library/ios/technotes/tn2154/_index.html

    当您在 subview 和 ScrollView 的内墙之间连接所有这些约束时,结果可能不是您所期望的。当您将 subview 固定到 ScrollView 的两侧时,您实际上并没有确定 subview 相对于 ScrollView 的位置。相反,您正在确定 ScrollView 的 contentSize .这很奇怪。

    您正在使用技术说明中 Apple 所谓的纯自动布局方法。使用这种方法, subview 的约束必须决定 ScrollView 的 contentSize .

    让我们只取您的一个 subview 并忽略所有其余的,比如 TextView 之一。让我们只考虑沿水平轴的 TextView 。如果您希望 TextView 在没有任何水平滚动的情况下受 ScrollView 的宽度约束,则需要在 TextView 上安装固定宽度约束,该约束恰好是 ScrollView 边界的宽度减去间隔符。这样做之后,内容大小宽度将是左间隔、 TextView 的宽度和右间隔的总和。

    不幸的是,您无法安装在 TextView 的宽度和 ScrollView 边界的宽度之间建立关系的约束。这真的太糟糕了。

    我实际上并不建议在 TextView 上安装固定宽度约束。相反,我会重新开始并使用 Apple 技术说明中的“混合方法”。

    使用混合方法, subview 的约束不会决定 ScrollView 的 contentSize .相反,您必须显式设置 ScrollView 的 contentSize和容器 View 的框架(即 UIView 内容 View )。

    让我们回到那个 UITextView和水平轴。使用混合方法,您可以保留 TextView 的约束(即没有固定宽度约束)。您可以显式设置 ScrollView 的宽度 contentSize和内容 View 框架的宽度早在viewDidLoad .您可以将这些值显式设置为 self.view.bounds.size.width因为您的 ScrollView 紧贴主 View 的两侧。

    要实现混合方法,您必须在代码中实例化内容 View ( UIView )和 不是 设置其 translatesAutoresizingMaskIntoConstraints属性(property)到NO .通过扩展,您可能还需要为代码中的所有这些 subview 创建约束(我不知道有任何解决方法)。视觉格式化字符串既乏味又重复,但在配置复杂布局(您的布局足够复杂)时,它们实际上比在 IB 中创建的约束更容易使用。

    我在这里使用混合方法解决了一个 SO 挑战:https://stackoverflow.com/a/21770179/1239263 .不幸的是,该解决方案尚未经过审查。我总是有可能疯了,我不知道我在说什么。

    关于ios - 没有明确的宽度约束和更大或相等的尾随空间行为不当的自动布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21761937/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com