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