如何设置 NSLayoutAnchor 以生成具有宽高比 1:1 的居中子视图
How to set the NSLayoutAnchor to generate an centered subview with aspect ratio 1:1
听起来并不太难,但经过几个小时的尝试我无法找到合适的解决方案。
问题:我想设置约束(使用 class NSLayoutAnchor)来让子视图(colorImageView)在父视图中 centered, 纵横比 1:1 并且总是在 最大尺寸 可能在超级视图中有时宽度 > 高度或高度 > 宽度。
示例 1: SuperViewSize = width : 80, height = 100 -> 子视图的高度和宽度应为 80 且居中于 (40/50)
示例 2: SuperviewSize = width : 60, height = 50 -> 子视图的高度和宽度应为 50 且居中于 (30/25)
我不想/它不能解决问题/硬编码一个 widthConstraint = min(superviewWidth, superviewHeight) 因为在创建子视图的那一刻,superviews 边界没有最终定义 -> 所以我需要一个约束。
这是我到目前为止的尝试(仍然缺少在不同的超级视图中将高度和宽度设置为最大可能的限制:
// CREATE CONSTRAINTS(center in SuperView)
colorImageView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
colorImageView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
// CREATE CONSTRAINTS (ratio 1:1)
colorImageView.widthAnchor.constraint(equalTo: colorImageView.heightAnchor, multiplier: 1.0).isActive = true
我真的很感激提示,如何做到这一点。提前致谢:))
完成这项工作的关键是将 colorImageView
的宽度设置为其父视图的宽度,但优先级为 750(而不是默认的 1000)。
然后将 colorImageView
的高度设置为 lessThanOrEqualTo
其父视图的高度。
Auto Layout 将尽力满足这两个新约束。
当视图的宽度大于它的高度时,它将无法使 colorImageView
的宽度等于视图的宽度,但这没关系,因为优先级为 750。它将使它在不违反其他完整优先级约束的情况下尽可能大。
当视图的高度大于其宽度时,它将能够满足所有约束,因为 colorView 的高度是 lessThanOrEqualTo
视图的高度。
import UIKit
let view = UIView(frame: CGRect(x: 0, y: 0, width: 80, height: 100))
view.backgroundColor = .red
let colorImageView = UIView()
colorImageView.translatesAutoresizingMaskIntoConstraints = false
colorImageView.backgroundColor = .yellow
view.addSubview(colorImageView)
// CREATE CONSTRAINTS(center in SuperView)
colorImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
colorImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
// CREATE CONSTRAINTS (ratio 1:1)
colorImageView.widthAnchor.constraint(equalTo: colorImageView.heightAnchor, multiplier: 1.0).isActive = true
let widthConstraint = colorImageView.widthAnchor.constraint(equalTo: view.widthAnchor)
widthConstraint.priority = UILayoutPriority(rawValue: 750)
widthConstraint.isActive = true
colorImageView.heightAnchor.constraint(lessThanOrEqualTo: view.heightAnchor).isActive = true
view.layoutIfNeeded()
view.frame = CGRect(x: 0, y: 0, width: 60, height: 50)
view.layoutIfNeeded()
这里是 运行 游乐场:
听起来并不太难,但经过几个小时的尝试我无法找到合适的解决方案。
问题:我想设置约束(使用 class NSLayoutAnchor)来让子视图(colorImageView)在父视图中 centered, 纵横比 1:1 并且总是在 最大尺寸 可能在超级视图中有时宽度 > 高度或高度 > 宽度。
示例 1: SuperViewSize = width : 80, height = 100 -> 子视图的高度和宽度应为 80 且居中于 (40/50)
示例 2: SuperviewSize = width : 60, height = 50 -> 子视图的高度和宽度应为 50 且居中于 (30/25)
我不想/它不能解决问题/硬编码一个 widthConstraint = min(superviewWidth, superviewHeight) 因为在创建子视图的那一刻,superviews 边界没有最终定义 -> 所以我需要一个约束。
这是我到目前为止的尝试(仍然缺少在不同的超级视图中将高度和宽度设置为最大可能的限制:
// CREATE CONSTRAINTS(center in SuperView)
colorImageView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
colorImageView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
// CREATE CONSTRAINTS (ratio 1:1)
colorImageView.widthAnchor.constraint(equalTo: colorImageView.heightAnchor, multiplier: 1.0).isActive = true
我真的很感激提示,如何做到这一点。提前致谢:))
完成这项工作的关键是将 colorImageView
的宽度设置为其父视图的宽度,但优先级为 750(而不是默认的 1000)。
然后将 colorImageView
的高度设置为 lessThanOrEqualTo
其父视图的高度。
Auto Layout 将尽力满足这两个新约束。
当视图的宽度大于它的高度时,它将无法使 colorImageView
的宽度等于视图的宽度,但这没关系,因为优先级为 750。它将使它在不违反其他完整优先级约束的情况下尽可能大。
当视图的高度大于其宽度时,它将能够满足所有约束,因为 colorView 的高度是 lessThanOrEqualTo
视图的高度。
import UIKit
let view = UIView(frame: CGRect(x: 0, y: 0, width: 80, height: 100))
view.backgroundColor = .red
let colorImageView = UIView()
colorImageView.translatesAutoresizingMaskIntoConstraints = false
colorImageView.backgroundColor = .yellow
view.addSubview(colorImageView)
// CREATE CONSTRAINTS(center in SuperView)
colorImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
colorImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
// CREATE CONSTRAINTS (ratio 1:1)
colorImageView.widthAnchor.constraint(equalTo: colorImageView.heightAnchor, multiplier: 1.0).isActive = true
let widthConstraint = colorImageView.widthAnchor.constraint(equalTo: view.widthAnchor)
widthConstraint.priority = UILayoutPriority(rawValue: 750)
widthConstraint.isActive = true
colorImageView.heightAnchor.constraint(lessThanOrEqualTo: view.heightAnchor).isActive = true
view.layoutIfNeeded()
view.frame = CGRect(x: 0, y: 0, width: 60, height: 50)
view.layoutIfNeeded()
这里是 运行 游乐场: