对图像视图使用SF Symbols
with 配置是非常古怪的。
我不知道我是否将其称为“错误”或只是未记录(或非常模糊记录)的行为。
像这样设置.image
a 的属性UIImageView
:
let conf = UIImage.SymbolConfiguration(pointSize: 10, weight: .medium, scale: .large)
let image = UIImage(systemName: "doc.fill", withConfiguration: conf)
imageView.image = image
将改变图像视图的框架!...不管限制。
这是一个明显的例子......
我们从 4 个图像视图开始,限制为 Width:80,Height:equalTo Width。红线被限制在每个图像视图的顶部和底部:
现在,我们设置每个 imageView 的图像,使用符号配置pointSize
(从 10.0 开始),weight: .medium
小scale:
、中、大,加上底部使用 NO 配置 -- img = UIImage(systemName: "doc.fill")
。
在 10.0 pointSize 时,我们已经可以看到图像视图帧的变化:
当我们达到 50.0 的点大小时,“奇怪的框架大小”非常明显:
这是一个像素精确的捕获:
这是此示例的代码,因此您可以更详细地检查所有内容:
class SFSymbolsViewController: UIViewController {
var imgViews: [UIImageView] = []
var labels: [[UILabel]] = []
// this will be incremented with each tap
var ptSize: CGFloat = 5.0
override func viewDidLoad() {
super.viewDidLoad()
let g = view.safeAreaLayoutGuide
let infoLabel = UILabel()
infoLabel.translatesAutoresizingMaskIntoConstraints = false
infoLabel.numberOfLines = 0
infoLabel.textAlignment = .center
infoLabel.font = .systemFont(ofSize: 14.0)
infoLabel.text = "Tap to add images.\nPointSize will start at 10, and each Tap will increment the Point Size by 5.0 and re-generate the images."
view.addSubview(infoLabel)
NSLayoutConstraint.activate([
infoLabel.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
infoLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
infoLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -40.0),
])
var y: CGFloat = 140
let yInc: CGFloat = 100
for _ in 1...4 {
let imageView = UIImageView()
imageView.backgroundColor = .systemYellow
imageView.contentMode = .scaleAspectFit
imageView.translatesAutoresizingMaskIntoConstraints = false
imgViews.append(imageView)
view.addSubview(imageView)
// horizontal "line" views
let h1 = UIView()
let h2 = UIView()
[h1, h2].forEach { v in
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .red
view.addSubview(v)
NSLayoutConstraint.activate([
v.heightAnchor.constraint(equalToConstant: 1.0),
v.widthAnchor.constraint(equalTo: g.widthAnchor),
v.centerXAnchor.constraint(equalTo: g.centerXAnchor),
])
}
// info labels
var imgLabels: [UILabel] = []
for _ in 1...3 {
let label = UILabel()
label.font = .systemFont(ofSize: 12.0)
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
// add label to right of imageView
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: 12.0),
label.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -12.0),
])
imgLabels.append(label)
}
imgLabels[1].text = "cfg:"
labels.append(imgLabels)
NSLayoutConstraint.activate([
// image view Top = y, Leading = 20
// width = 80, height = width (1:1 ratio)
imageView.topAnchor.constraint(equalTo: g.topAnchor, constant: y),
imageView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
imageView.widthAnchor.constraint(equalToConstant: 80.0),
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor),
// put a "line" on top and bottom of imageView
h1.bottomAnchor.constraint(equalTo: imageView.topAnchor),
h2.topAnchor.constraint(equalTo: imageView.bottomAnchor),
// label y positions
imgLabels[0].topAnchor.constraint(equalTo: h1.bottomAnchor, constant: 4.0),
imgLabels[1].centerYAnchor.constraint(equalTo: imageView.centerYAnchor),
imgLabels[2].bottomAnchor.constraint(equalTo: h2.topAnchor, constant: -4.0),
])
y += yInc
}
let t = UITapGestureRecognizer(target: self, action: #selector(self.setImages(_:)))
view.addGestureRecognizer(t)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
updateSizeLabels(true)
}
func updateSizeLabels(_ orig: Bool) -> Void {
for (l, v) in zip(labels, imgViews) {
if orig {
l[0].text = "Orig Frame: \(v.frame)"
}
l[2].text = "New Frame: \(v.frame)"
}
}
@objc func setImages(_ g: UITapGestureRecognizer) -> Void {
ptSize += 5.0
var cfg: UIImage.SymbolConfiguration!
var img: UIImage!
var i: Int = 0
labels[i][1].text = "cfg: \(ptSize) / medium / small"
cfg = UIImage.SymbolConfiguration(pointSize: ptSize, weight: .medium, scale: .small)
img = UIImage(systemName: "doc.fill", withConfiguration: cfg)
imgViews[i].image = img
i += 1
labels[i][1].text = "cfg: \(ptSize) / medium / medium"
cfg = UIImage.SymbolConfiguration(pointSize: ptSize, weight: .medium, scale: .medium)
img = UIImage(systemName: "doc.fill", withConfiguration: cfg)
imgViews[i].image = img
i += 1
labels[i][1].text = "cfg: \(ptSize) / medium / large"
cfg = UIImage.SymbolConfiguration(pointSize: ptSize, weight: .medium, scale: .large)
img = UIImage(systemName: "doc.fill", withConfiguration: cfg)
imgViews[i].image = img
i += 1
labels[i][1].text = "cfg: NO SymbolConfiguration"
img = UIImage(systemName: "doc.fill")
imgViews[i].image = img
// update the size labels after UI updates
DispatchQueue.main.async {
self.updateSizeLabels(false)
}
}
}
底线:我相信配置选项与字体的配合更直接相关。以这种方式使用 SF Symbols 时,最好不要使用UIImage.SymbolConfiguration
(除非您无法获得所需的外观,在这种情况下,您可能需要跳过一些步骤才能正确调整大小/对齐方式)。