Instruction

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Attributed Strings

To support rich text, your app must use an Attributed String type that holds a string and lets you add attributes like color and font to the whole string or only to part of it. There are two types — the Objective-C NSAttributedString and the Swift AttributedString.

NSAttributedString

A NSAttributedString object holds a string plus key-value pairs (attributes) that specify additional information to apply to ranges of characters within the string. Attributes include:

AttributedString

AttributedString is a Swift struct introduced in iOS 15, enabling Swift devs to create styled text Swiftly. Attributes provide features such as visual styles for display, accessibility guidance, and hyperlink data for linking between data sources.

NSAttributedString vs AttributedString

Initializing an NSAttributedString with a String and an attributes dictionary:

let string = "Attributed String"
let attributes: [NSAttributedString.Key : Any] = [
    NSAttributedString.Key.foregroundColor: UIColor.systemPink,
    NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 40),
    NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue
]
let attributedString = NSAttributedString(string: string, attributes: attributes)

let label = UILabel()
label.attributedText = attributedString
private var attributedString: AttributedString {
    let string = "Attributed String"
    var attributedString = AttributedString(string)
    
    attributedString.foregroundColor = .pink
    attributedString.font = .boldSystemFont(ofSize: 40)
    attributedString.underlineStyle = .single

    return attributedString
}

var body: some View {
    Text(attributedString)
}

NSAttributedString <==> AttributedString

You can convert one to the other, but each type has attributes that the other doesn’t. Keeping this in mind, you can leverage the strengths of each type. For example:

Adaptive Image Glyphs

An Adaptive Image Glyph is a data object for an emoji-like image that can appear in attributed text. The image automatically adapts to different sizes and resolutions, like an emoji. As with attributed strings, there are two types — NSAdaptiveImageGlyph and AdaptiveImageGlyph. At the time of writing, the API seems to support NSAdaptiveImageGlyph more than AdaptiveImageGlyph.

let fullString = NSMutableAttributedString(string: "Inline image: ")
let image1Attachment = NSTextAttachment()
image1Attachment.image = UIImage(systemName: "globe")
let image1String = NSAttributedString(attachment: image1Attachment)
fullString.append(image1String)

let label = UILabel()
label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
label.attributedText = fullString
label.textColor = .black
view.addSubview(label)

NSAdaptiveImageGlyph

An NSAdaptiveImageGlyph contains an image that automatically adapts to different sizes and resolutions. This type manages multiple images, along with metadata describing how to adapt those images correctly to different fonts and font attributes. It’s another type of attachment to an NSAttributedString object.

init(imageContent: Data)
init(coder: NSCoder)

AdaptiveImageGlyph

AdaptiveImageGlyph is a struct component of AttributedString. Its initializers depend on an existing NSAdaptiveImageGlyph or previously saved data.

init(NSAdaptiveImageGlyph)
init(from: any Decoder)
init(imageContent: Data)
convenience init(
  adaptiveImageGlyph: NSAdaptiveImageGlyph,
  attributes: [NSAttributedString.Key : Any] = [:]
)

Waiting for the Updated Emoji Keyboard

According to the documentation, the only way to create an attributed string with an adaptive image glyph is via the text input system, using the new emoji keyboard. To try this in a simulator, you could drag a sticker into Photos, then see if you can add it to a text field. But it’s not (yet) appearing in the emoji keyboard. At the time of writing, iOS 18 on an iPhone XR doesn’t add a sticker alongside message text. Another possible approach is to type text containing a custom emoji into a native Sequoia app like TextEdit, then copy and paste that string into a simulator text field but, as of Sequoia beta 3, that’s not working.

See forum comments
Download course materials from Github
Previous: Introduction Next: Foreword