【问题标题】:Use AutoLayout to position percentage-positioned subviews inside UIView使用 AutoLayout 在 UIView 中定位百分比定位的子视图
【发布时间】:2020-07-23 01:03:18
【问题描述】:

我正在使用一些 JSON,它为我提供了一系列视图和子视图以在 UIView 内进行布局,我想使用 AutoLayout 来实现它。这是 JSON 的示例:

"component": {
    "width": 150,
    "height": 100,
    "elements": [
        {
            "x": 0.1,
            "y": 0.1,
            "w": 0.8,
            "h": 0.8
        }   
    ]
}

在本例中,外部视图(component 视图)要求的尺寸为 150 x 100。我的布局是基于屏幕宽度保持纵横比,如下所示:

private func fittedSize(for dimensions: Dimensions) -> CGSize {
    var width: CGFloat
    var height: CGFloat

    if dimensions.width.value > dimensions.height.value {
        let aspectRatio = dimensions.height.value / dimensions.width.value
        width = dimensions.width.value
        height = dimensions.width.value * aspectRatio
    } else {
        let aspectRatio = dimensions.width.value / dimensions.height.value
        height = dimensions.height.value
        width = dimensions.height.value * aspectRatio


    let apertureSize = CGSize(width: width, height: height)

    if apertureSize.width > apertureSize.height {
        let scale = bounds.width / apertureSize.width
        return CGSize(width: apertureSize.width * scale, height: apertureSize.height * scale)
    } else {
        let scale = bounds.height / apertureSize.height
        return CGSize(width: apertureSize.width * scale, height: apertureSize.height * scale)
    }
}

上述函数计算视图在保持其尺寸指定的纵横比的同时可以达到的最大尺寸,例如,在屏幕宽度为 320 时,100x150 的视图将是 320x480。

我现在需要布局该视图的子视图,包含该组件中的元素。这些值被指定为百分比,因此在上面的示例中,元素应位于从左侧和顶部开始的宽度的 10%,以及父视图宽度和高度的 80%。

我可以使用带乘数的约束轻松获得正确的宽度和高度,如下所示:

let w = elementView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: element.position.width)
let h = elementView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: element.position.height)

这将采用 0.8,并使子视图为其父级宽度和高度的 80%。问题在于我还想对其位置(x 和 y)使用乘数。 AutoLayout 不支持这个,这就是我要找的答案。

如何使用 AutoLayout 而不是手动定位框架,使用百分比值在另一个 UIView 中定位和调整大小?

注意事项:

以下是当前布局的示例。红色区域是子视图,浅蓝色区域是父视图。请注意,子视图的大小是正确的,宽度和高度的 80%,但它没有显示从顶部和左侧进入的 10%,这就是我所缺少的。

【问题讨论】:

    标签: ios swift autolayout nslayoutconstraint


    【解决方案1】:

    您可以使用UILayoutGuide 或虚拟视图,并限制超级视图的前沿和视图的前沿,并通过乘数将此“间隔”视图宽度限制为其超级视图宽度。

    let l = view.leadingAnchor.constraint(equalTo: view.leadingSpacer.leadingAnchor)
    let w = leadingSpacer.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: element.position.x)
    let t = leadingSpacer.trailingAnchor.constraint(to: elementView.leadingAnchor)
    

    并激活此约束

    对顶部垫片做类似的事情。 我已经为这个问题使用了虚拟视图,但UILayoutGuide 被提议为更有效的解决方案,因为它只与 AutoLayout 引擎交互并且不参与渲染。希望这会有所帮助。

    【讨论】:

    • 您还需要约束此间隔的视图顶部和底部锚点,以使布局明确
    【解决方案2】:

    您还需要提供顶部和左侧约束。 类似下面的东西

    elementView.topAnchor.constraint(equalTo: view.topAnchor, constant: height / 10),
    elementView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: width / 10),
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-26
      • 2017-12-30
      • 1970-01-01
      相关资源
      最近更新 更多