I think that’s unfortunately the normal behavior, but I considered it as a forgotten feature non-dev by Apple.
The only way I got currently, is to listen to func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
to detect the mode change.
Then, you can either reconstruct your NSAttributedString
, or enumerate over it and update it when needed.
With a enumeration, ie update only what’s needed, and not regenerate the whole NSAttributedString
:
In your initial attachment creation:
let attachment = NSTextAttachment(image: asset.image(with: traitCollection))
let attachmentCharacter = NSAttributedString(attachment: attachment)
Side note:
I used asset.image(with: traitCollection)
instead of image1
, else when starting with dark mode, your image will be of light mode instead. So this should set the correct image.
Then, I’d update it with:
func switchAttachment(for attr: NSAttributedString?) -> NSAttributedString? {
guard let attr = attr else { return nil }
let mutable = NSMutableAttributedString(attributedString: attr)
mutable.enumerateAttribute(.attachment, in: NSRange(location: 0, length: mutable.length), options: []) { attachment, range, stop in
guard let attachment = attachment as? NSTextAttachment else { return }
guard let asset = attachment.image?.imageAsset else { return }
attachment.image = asset.image(with: .current)
mutable.replaceCharacters(in: range, with: NSAttributedString(attachment: attachment))
}
return mutable
}
And update when:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
label.attributedText = switchAttachment(for: label.attributedText)
}
CLICK HERE to find out more related problems solutions.