3

I'm working to replace NSAttributedString with AttributedString but have been unsuccessful in getting attachments to work. The image doesn't appear in the string despite the fact I applied the attachment.

let textAttachment = NSTextAttachment(image: UIImage(systemName: "exclamationmark.triangle.fill")!)
textAttachment.accessibilityLabel = "Warning"

// Original code
label.attributedText = NSAttributedString(attachment: textAttachment)

// New code
var attributedString = AttributedString()
attributedString.attachment = textAttachment
label.attributedText = NSAttributedString(attributedString)
MariaUngur
  • 52
  • 11
Jordan H
  • 52,571
  • 37
  • 201
  • 351

1 Answers1

5

NSAttributedString(attachment:) magically creates an NSAttributedString with a single character (NSAttachmentCharacter which is U+FFFC OBJECT REPLACEMENT CHARACTER) and applies the text attachment attribute in order to replace that character with the image.

With the new AttributedString API you'll need to manually replicate that:

let textAttachment = NSTextAttachment(image: UIImage(systemName: "exclamationmark.triangle.fill")!)
textAttachment.accessibilityLabel = "Warning"

let attributedString = AttributedString("\(UnicodeScalar(NSTextAttachment.character)!)", attributes: AttributeContainer.attachment(textAttachment))

label.attributedText = NSAttributedString(attributedString)

Here's an example that replaces a substring with an image:

let addString = "+"
let string = "Tap \(addString) to add a task."
let addTextAttachment = NSTextAttachment(image: UIImage(systemName: "plus.square")!)

// NSAttributedString
label.attributedText = {
    let attributedString = NSMutableAttributedString(string: string)
    attributedString.replaceCharacters(in: (attributedString.string as NSString).range(of: addString), with: NSAttributedString(attachment: addTextAttachment))
    return attributedString
}()

// AttributedString
label.attributedText = {
    var attributedString = AttributedString(string)
    let attachmentString = AttributedString("\(UnicodeScalar(NSTextAttachment.character)!)", attributes: AttributeContainer.attachment(addTextAttachment))
    attributedString.replaceSubrange(attributedString.range(of: addString)!, with: attachmentString)
    return NSAttributedString(attributedString)
}()
Jordan H
  • 52,571
  • 37
  • 201
  • 351