systemLayoutSizeFitting returns 始终为零
systemLayoutSizeFitting returns zero always
基于 Apple 的 doc,systemLayoutSizeFitting
应该在返回最佳尺寸时尊重 UIView
元素的当前约束。但是,每当我 运行 跟随代码时,我会得到 UIView.layoutFittingCompressedSize
的 {0, 0}
和 UIView.layoutFittingExpandedSizeSize
输入的 {1000, 1000}
。
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)
.
中获得正确的值
这方面的文档似乎相当缺乏。
看来 .systemLayoutSizeFitting
高度依赖于元素的 .intrinsicContentSize
。对于 UIView
,它没有固有的内容大小(除非您已覆盖它)。
因此,如果相关约束是另一个约束的 百分比 ,则 .systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
将 return {0, 0}
。我认为这是因为相关约束可能会更改(变为零),因此最小值实际上为零。
如果您将 .width
约束更改为常量(例如 mainView.frame.width * 0.3333
),那么您将获得有效的尺寸值,因为恒定宽度约束变为固有宽度。
例如,如果您的子视图是 UILabel
,该元素 将 具有固有大小,并且 .systemLayoutSizeFitting
应该 return您期望的尺寸值。
这是一个使用 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)
基于 Apple 的 doc,systemLayoutSizeFitting
应该在返回最佳尺寸时尊重 UIView
元素的当前约束。但是,每当我 运行 跟随代码时,我会得到 UIView.layoutFittingCompressedSize
的 {0, 0}
和 UIView.layoutFittingExpandedSizeSize
输入的 {1000, 1000}
。
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)
.
这方面的文档似乎相当缺乏。
看来 .systemLayoutSizeFitting
高度依赖于元素的 .intrinsicContentSize
。对于 UIView
,它没有固有的内容大小(除非您已覆盖它)。
因此,如果相关约束是另一个约束的 百分比 ,则 .systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
将 return {0, 0}
。我认为这是因为相关约束可能会更改(变为零),因此最小值实际上为零。
如果您将 .width
约束更改为常量(例如 mainView.frame.width * 0.3333
),那么您将获得有效的尺寸值,因为恒定宽度约束变为固有宽度。
例如,如果您的子视图是 UILabel
,该元素 将 具有固有大小,并且 .systemLayoutSizeFitting
应该 return您期望的尺寸值。
这是一个使用 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)