【发布时间】:2022-02-08 00:22:07
【问题描述】:
我有一张适用于明暗模式的动态图像。如果我将此图像放在 UIImageView 中,则动态会起作用:当用户从亮模式切换到暗模式并返回时,图像会更改显示的自身版本。但是,如果我将相同的图像作为 NSTextAttachment 放置在 NSAttributedString 中并在标签中显示字符串,则动态不起作用:当用户从浅色模式切换到深色模式时,图像不会改变。
要查看实际问题,请将此代码粘贴到您的viewDidLoad:
let size = CGSize(width: 20, height: 20)
let renderer = UIGraphicsImageRenderer(size: size)
let image1 = renderer.image {
UIColor.red.setFill()
$0.fill(.init(origin: .zero, size: size))
}
let image2 = renderer.image {
UIColor.green.setFill()
$0.fill(.init(origin: .zero, size: size))
}
let asset = UIImageAsset()
asset.register(image1, with: .init(userInterfaceStyle: .light))
asset.register(image2, with: .init(userInterfaceStyle: .dark))
let iv = UIImageView(image: image1)
iv.frame.origin = .init(x: 100, y: 100)
self.view.addSubview(iv)
let text = NSMutableAttributedString(string: "Howdy ", attributes: [
.foregroundColor: UIColor(dynamicProvider: { traits in
switch traits.userInterfaceStyle {
case .light: return .red
case .dark: return .green
default: return .red
}
})
])
let attachment = NSTextAttachment(image: image1)
let attachmentCharacter = NSAttributedString(attachment: attachment)
text.append(attachmentCharacter)
let label = UILabel()
label.attributedText = text
label.sizeToFit()
label.frame.origin = .init(x: 100, y: 150)
self.view.addSubview(label)
我特意使文本字体颜色动态化,以便您可以看到通常颜色动态确实在属性字符串中起作用。但不在属性字符串的文本附件中!
那么:这真的是 iOS 的行为方式,还是我在配置文本附件的方式上犯了一些错误?如果这就是 iOS 的行为方式,您是如何解决这个问题的?
[请注意,我不能使用 iOS 15 附件视图提供程序,因为我必须与 iOS 13 和 14 兼容。所以也许这可以解决问题,但该解决方案对我不开放。]
【问题讨论】:
-
我认为,这是正常行为。恐怕您需要在模式更改时使用
func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)重新计算NSAttributedString,而不是NSTextAttachment(image: image1),而是使用let attachment = NSTextAttachment(image: asset.image(with: traitCollection))。 -
由于
NSTextAttachment持有UIImage并且UIImage不知道模式,只有asset知道,不幸的是我发现这是正常行为。 -
@Larme 实际上在重绘属性字符串时不需要参考
asset,因为所讨论的特征集合是最新的。我在这里要指出的问题是具有讽刺意味的是,图像 in an image view 处于暗模式,而属性字符串 color 处于暗模式,但是属性字符串中的图像不是实时的。在我看来,这像是一个错误:苹果似乎只是在实施暗模式时错误地忘记了它。 -
我的意思是,当您执行
NSTextAttachment(image: image1)时,您不会告诉NSTextAttachmentimage1是一种模式,而应该是第二种模式?我也认为它是一个被遗忘的 iOS 开发者,我得到的唯一方法就是听traitCollectionDidChange()。
标签: ios nsattributedstring darkmode