使用
UIListContentConfiguration
时,如果您提供SF符号image
,系统会根据您的动态类型文本大小决定如何调整其大小。 reservedLayoutSize
文档指出:“符号图像将在预定义的reservedLayoutSize
内居中,并根据内容大小类别进行缩放。”另请注意,对于 Mac Catalyst,图像大小由您在系统偏好设置 > 常规 > 侧边栏图标大小中的设置决定。
在我的应用程序中,我想创建一个带有像照片应用程序这样的单元格的侧边栏 - 相册单元格包含图像照片而不是符号。为此,我需要知道图像的大小,以确保其与其他单元格中的符号大小相同,因为单元格图像视图的大小由您提供的图像的大小决定。 “非符号图像将使用等于显示图像实际尺寸的
reservedLayoutSize
。”
如何获取预定义的系统预留布局尺寸?
UIListContentConfiguration.ImageProperties.standardDimension
听起来很有希望,但这只是一个常量,通知系统使用其默认大小,而不是公开该大小 - 它的值为 -1.7976931348623157e+308。
contentConfiguration.imageProperties.reservedLayoutSize
默认为CGSize.zero
,表示使用默认大小。那么我们如何获得这个尺寸呢?
按照文档正常使用:
您无法获取尺寸,但可以使用它来设置reservedLayoutSize高度或宽度。然后,您必须根据当前文本大小调整图像大小。这考虑了文本大小选项和辅助功能选项。这是正常的使用方法:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let font = UIFont.preferredFont(forTextStyle: .body)
let currentFontHeight = font.lineHeight
let originalImage = UIImage(named: "ImageNameInAsset")!
let scaleFactor = currentFontHeight / originalImage.size.height
let scaledImage = originalImage.resized(scaleFactor: scaleFactor)
var config = cell.defaultContentConfiguration()
config.image = scaledImage
config.text = "Text"
config.imageProperties.reservedLayoutSize.width = UIListContentConfiguration.ImageProperties.standardDimension
config.imageProperties.reservedLayoutSize.height = UIListContentConfiguration.ImageProperties.standardDimension
config.imageProperties.cornerRadius = 3
cell.contentConfiguration = config
return cell
检索实际宽度和高度:
如果您想检索图像的实际宽度和高度并从那里开始工作,您必须解决 UIListContentConfiguration.ImageProperties.standardDimension 的奇怪行为,我创建了此类来以相同的方式布局自定义图标图像作为 SF 符号的布局。
技巧是在 contentConfiguration 中设置一个“清晰”的 SF Symbol 作为图像,然后设置自定义图像。然后,自定义图像符合 UIListContentView 内的 imageLayoutGuide 提供的约束以匹配布局。它将自定义图像居中。
也许也可以创建一个自己的 contentConfiguration 类,但这现在对我有用。我希望它足够优雅来解决您的问题。它甚至可以根据不同的文本大小或辅助功能选项进行缩放。
使用方法如下:
// In the tableview setup:
tableView.register(CustomImageViewCell.self, forCellReuseIdentifier: "customImageViewCell")
// When dequeuing a cell
let cell = tableView.dequeueReusableCell(withIdentifier: "customImageViewCell", for: indexPath) as! CustomImageViewCell
var config = cell.defaultContentConfiguration()
let imageConfig = UIImage.SymbolConfiguration.init(hierarchicalColor: .clear)
let image = UIImage(systemName: "calendar")?.withConfiguration(imageConfig)
config.image = image
config.text = "Label"
cell.contentConfiguration = config
// This image will get overlayed in the custom class later on
cell.setCustomImage(UIImage(named: "YourAssetName"))
return cell
这是自定义类:
class CustomImageViewCell: UITableViewCell {
private let customImageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.layer.cornerRadius = 3
imageView.clipsToBounds = true
return imageView
}()
private var didSetupConstraints = false
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func willMove(toSuperview newSuperview: UIView?) {
super.willMove(toSuperview: newSuperview)
if !didSetupConstraints {
if let contentView = contentView as? UIListContentView,
let imageLayoutGuide = contentView.imageLayoutGuide {
contentView.addSubview(customImageView)
NSLayoutConstraint.activate([
customImageView.topAnchor.constraint(equalTo: imageLayoutGuide.topAnchor),
customImageView.bottomAnchor.constraint(equalTo: imageLayoutGuide.bottomAnchor),
customImageView.centerXAnchor.constraint(equalTo: imageLayoutGuide.centerXAnchor),
customImageView.widthAnchor.constraint(equalTo: imageLayoutGuide.heightAnchor)
])
didSetupConstraints = true
}
}
}
func setCustomImage(_ image: UIImage?) {
customImageView.image = image
}
}