Swift:自动布局以编程方式导致错误的帧大小(小数)
Swift: Autolayout programmatically results in wrong frame size (decimals)
我正在尝试在容器视图中设置 9:16 方面视图。下面的代码在viewDidLayoutSubviews
中设置了约束,这样在合适的地方就可以考虑Autolayout了。它还调用 layoutIfNeeded
.
虽然 maxWidth
的计算是正确的(在 iPhone X 上:609.7777777777778),但设置的约束将创建错误的帧大小(在 iPhone X 上: 609.6666666666666).
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var orangeContainerView: UIView!
var inset: CGFloat = 16
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
setupAutolayout()
}
func setupAutolayout() {
let aspectRatioView = UIView()
aspectRatioView.backgroundColor = .blue
orangeContainerView.addSubview(aspectRatioView)
aspectRatioView.translatesAutoresizingMaskIntoConstraints = false
// Set up a 9:16 view
// calculate max width, and based on that the max height and see if it fits into the container
let maxWidth = orangeContainerView.frame.width - (2 * inset)
let targetHeight = maxWidth / 9 * 16
if targetHeight <= orangeContainerView.frame.height {
print("FRAME SIZE SHOULD BE: \(maxWidth) x \(targetHeight)")
aspectRatioView.topAnchor.constraint(equalTo: orangeContainerView.topAnchor).isActive = true
aspectRatioView.centerXAnchor.constraint(equalTo: orangeContainerView.centerXAnchor).isActive = true
aspectRatioView.widthAnchor.constraint(equalToConstant: maxWidth).isActive = true
aspectRatioView.heightAnchor.constraint(equalToConstant: targetHeight).isActive = true
}
orangeContainerView.layoutIfNeeded()
print(aspectRatioView.frame)
}
}
在iPhone X 模拟器中打印如下:
FRAME SIZE SHOULD BE: 343.0 x 609.7777777777778
(16.0, 0.0, 343.0, 609.6666666666666)
IB截图:
帧坐标不能随意
如果设备比例为 2(例如 iPhone 8),框架边界将四舍五入为 1/2 磅。
如果设备比例为 3(例如 iPhone X),框架边界将四舍五入为 1/3 点。
因此,当您的浮点计算结果为 609.7777777777778
时,将该值设置为宽度约束将为您提供实际帧宽度:
- 在 iPhone X 上:
609.6666666666666
(609 和 2/3)
- 在 iPhone 8 上:
610.0
我正在尝试在容器视图中设置 9:16 方面视图。下面的代码在viewDidLayoutSubviews
中设置了约束,这样在合适的地方就可以考虑Autolayout了。它还调用 layoutIfNeeded
.
虽然 maxWidth
的计算是正确的(在 iPhone X 上:609.7777777777778),但设置的约束将创建错误的帧大小(在 iPhone X 上: 609.6666666666666).
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var orangeContainerView: UIView!
var inset: CGFloat = 16
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
setupAutolayout()
}
func setupAutolayout() {
let aspectRatioView = UIView()
aspectRatioView.backgroundColor = .blue
orangeContainerView.addSubview(aspectRatioView)
aspectRatioView.translatesAutoresizingMaskIntoConstraints = false
// Set up a 9:16 view
// calculate max width, and based on that the max height and see if it fits into the container
let maxWidth = orangeContainerView.frame.width - (2 * inset)
let targetHeight = maxWidth / 9 * 16
if targetHeight <= orangeContainerView.frame.height {
print("FRAME SIZE SHOULD BE: \(maxWidth) x \(targetHeight)")
aspectRatioView.topAnchor.constraint(equalTo: orangeContainerView.topAnchor).isActive = true
aspectRatioView.centerXAnchor.constraint(equalTo: orangeContainerView.centerXAnchor).isActive = true
aspectRatioView.widthAnchor.constraint(equalToConstant: maxWidth).isActive = true
aspectRatioView.heightAnchor.constraint(equalToConstant: targetHeight).isActive = true
}
orangeContainerView.layoutIfNeeded()
print(aspectRatioView.frame)
}
}
在iPhone X 模拟器中打印如下:
FRAME SIZE SHOULD BE: 343.0 x 609.7777777777778
(16.0, 0.0, 343.0, 609.6666666666666)
IB截图:
帧坐标不能随意
如果设备比例为 2(例如 iPhone 8),框架边界将四舍五入为 1/2 磅。
如果设备比例为 3(例如 iPhone X),框架边界将四舍五入为 1/3 点。
因此,当您的浮点计算结果为 609.7777777777778
时,将该值设置为宽度约束将为您提供实际帧宽度:
- 在 iPhone X 上:
609.6666666666666
(609 和 2/3) - 在 iPhone 8 上:
610.0