【问题标题】:How to make a square view resize with its superview using auto layout如何使用自动布局使用其超级视图调整方形视图的大小
【发布时间】:2015-08-19 15:38:01
【问题描述】:

在我的特殊情况下,我在视图控制器中有视图,为此我添加了以下约束:

  • 将前缘、后缘、顶边和底边设置为 0
  • 将底边的乘数设置为 2:1

现在视图位于视图控制器的上半部分。

在其中我添加了一个方形图像视图,为此我添加了以下约束:

  • Ctrl 从图像视图拖动到超级视图并添加相等的高度和宽度。
  • 更改宽度和高度的乘数,直到我有一个完美的正方形。
  • 添加了垂直和水平居中的约束

我的约束看起来很完美,但是在模拟器中运行时,我没有得到一个完美的正方形。除此之外,在不同的模拟器屏幕上运行时,图像视图不会调整大小。

这是我的设置:

  • 已启用自动布局和大小类
  • 我为情节提要使用推断大小
  • 自适应布局设置为任意宽度和高度
  • 我正在尝试为 4s、5、6 和 6+ 模拟器运行此程序。

我查看了其他 stackoverflow 帖子,但似乎没有任何效果。

是否有一些基本步骤可以做到这一点?

编辑:

设置>=10个约束后:

编辑3:我添加了顶部,底部,前导,尾随约束2次,1次小于或等于(优先级1000),另一个大于或等于(优先级800),常数值为90。我不知道为什么底部它试图从主视图延伸到 90 pt,而不是容器视图(绿色)。

【问题讨论】:

  • 您应该在要保持正方形的视图上使用 1:1 的 aspectRatio 约束,然后仅包含其父级的高度或宽度,但不能同时包含两者。
  • 所以只需将纵横比设置为 1:1 并设置与超级视图成比例的高度或宽度?这样做我得到一个正方形(很小),但它不会根据屏幕调整大小,所有屏幕上的大小相同

标签: ios swift autolayout


【解决方案1】:

您的视图需要扩展以填充其容器,同时保持其纵横比。这是 Auto Layout 的常见模式。

诀窍是对前导/尾随/顶部/底部使用两个约束:

  • =10 处于低优先级

  • >=10 在所需的优先级。

综合起来,你有:

  • 纵横比 1:1

  • 在 Superview 中居中 X/Y

  • 前导/尾随/顶部/底部到 Superview = 10(750 优先级)

  • Superview >= 10(优先级为 1000)

UIImageView 还需要考虑一些事项:

  • UIImageView 将具有基于它所显示图像的固有内容大小,因此您需要确保其 Content Hugging Priority 低于您用于 =10 约束的 750 优先级。

  • UIImageView.contentMode 确定基础图像相对于 UIImageView 大小的大小。默认设置为UIViewContentModeScaleToFill

【讨论】:

  • 它有效,但我有一个问题。在 4s 上,正方形看起来太小了,我可以以某种方式控制它吗?在 6 和 5s 屏幕上,尺寸还可以。
  • @Adrian 您可以在图像的超级视图上使用最小高度限制。例如:height=superview.height*0.5 @ 优先级 900,高度 >= 350 @ 优先级 1000
  • @darren,谢谢。我必须引入 1 个新约束,例如 Img.height = 0.25 x superview.height@900 以按比例增加图像的大小 x 0.25 倍,因为图像从 iPhone 6 到 6 Plus 的大小急剧增长。
  • 如何添加所有这些Leading/Trailing/Top/Bottom to Superview
【解决方案2】:
container view
----------------------------------------------
|                     |                      |
|                    >=10                    |
|        imageView    |                      |
|        ----------------------------        |
|        |            |             |        |      
|        |            |             |        |
|        |            |             |        |
|        |            |             |        |
|        |            |             |        |
|- >=10 -|---------- 1:1 -----------|- >=10 -|
|        |            |             |        |
|        |            |             |        |
|        |            |             |        |
|        |            |             |        |
|        ----------------------------        |
|                     |                      |
|                    >=10                    |
|                     |                      |
----------------------------------------------

**如果你愿意,你可以指定 imageView 的高度或宽度以及较低的优先级约束。

【讨论】:

  • 你能告诉我你是如何设置这些约束的吗?我只是添加一个前导、尾随、底部和顶部约束并选择大于或等于并将常量设置为 10 或如何?
  • 是的,就像你说的那样,然后给图片添加一个1:1的纵横比(cntrl+拖动)图片到自己。
  • 它对我不起作用。我附上了一张截图来看看它的样子。
  • 您将如何以编程方式翻译此内容? @DannyBravo
【解决方案3】:

我成功使用了这个配置。

  1. 我所做的是首先为中心 X 添加约束。(忽略中心 Y,即使它在我的屏幕截图中。由于第 2 步,它都会中断。)

  2. 然后我添加了上下约束

  3. 最后我添加了纵横比约束

当我对此进行动画处理时,框正确地缩放为正方形。如果你愿意,我可以上传测试项目。

【讨论】:

    【解决方案4】:

    在代码中,对于 realz.注意:奇怪的CGFloat.greatestFiniteMagnitude 是必要的(或者是更大的数字)来获取其他约束。享受吧。

    extension UIView {
        func constrainAsSquare(container: UIView, multiplier: CGFloat) {
            translatesAutoresizingMaskIntoConstraints = false
    
            centerXAnchor.constraint(equalTo: container.centerXAnchor).isActive = true
            centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true
    
            widthAnchor.constraint(equalToConstant: .greatestFiniteMagnitude).activate(with: .defaultLow)
    
            heightAnchor.constraint(lessThanOrEqualTo: container.heightAnchor, multiplier: multiplier).activate(with: .defaultHigh)
            widthAnchor.constraint(lessThanOrEqualTo: container.widthAnchor, multiplier: multiplier).activate(with: .defaultHigh)
    
            widthAnchor.constraint(equalTo: heightAnchor).activate(with: .required)
        }
    }
    
    extension NSLayoutConstraint {
        @discardableResult
        func activate(with priority: UILayoutPriority) -> NSLayoutConstraint {
            self.priority = priority
            isActive = true
            return self
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-10
      • 1970-01-01
      • 1970-01-01
      • 2012-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多