首页 > 解决方案 > systemLayoutSizeFitting 总是返回零

问题描述

基于 Apple 的文档,在返回最佳尺寸时systemLayoutSizeFitting应该尊重UIView元素的当前约束。但是,每当我运行以下代码时,我都会得到{0, 0}forUIView.layoutFittingCompressedSize{1000, 1000}forUIView.layoutFittingExpandedSizeSize输入。

let mainView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 375, height: 50)))
mainView.backgroundColor = .red
PlaygroundPage.current.liveView = mainView

let subview = UIView()
subview.backgroundColor = .yellow
mainView.addSubview(subview)
subview.snp.makeConstraints { make in
    make.width.equalToSuperview().dividedBy(3.0)
    make.left.top.bottom.equalToSuperview()
}
mainView.setNeedsLayout()
mainView.layoutIfNeeded()

subview.frame

subview.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)

我注意到,如果我将width约束更改为常量,那么我会从systemLayoutSizeFitting. 试图了解为什么会发生这种行为,以及是否有可能从systemLayoutSizeFittingSize(_ size: CGSize).

标签: iosautolayout

解决方案


这方面的文档似乎相当缺乏。

看来这.systemLayoutSizeFitting高度依赖于.intrinsicContentSize元素的。在 a 的情况下UIView,它没有内在的内容大小(除非您已覆盖它)。

因此,如果相关约束是另一个约束的百分比.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)将返回{0, 0}. 我认为这是因为相关约束可能会更改(为零),因此最小值实际上为零。

如果您将.width约束更改为常量(例如mainView.frame.width * 0.3333),那么您将获得一个有效的大小值,因为常量宽度约束变为固有宽度。

UILabel例如,如果您的子视图是,则该元素具有固有大小,并且.systemLayoutSizeFitting应该返回您期望的大小值。

这是一个使用 a 的示例UILabel,它将演示:

import UIKit
import PlaygroundSupport

let mainView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 375, height: 50)))
mainView.backgroundColor = .red
PlaygroundPage.current.liveView = mainView

let v = UILabel()
v.text = "Testing"
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .green
mainView.addSubview(v)

NSLayoutConstraint.activate([
    v.widthAnchor.constraint(equalTo: mainView.widthAnchor, multiplier: 3.0 / 10.0),
    v.leftAnchor.constraint(equalTo: mainView.leftAnchor),
    v.topAnchor.constraint(equalTo: mainView.topAnchor),
    v.bottomAnchor.constraint(equalTo: mainView.bottomAnchor),
    ])

mainView.setNeedsLayout()
mainView.layoutIfNeeded()

v.frame

v.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)

推荐阅读