Skip to content

Subclass of UILabel that simplifies work with rich text, providing Markup processing, custom links styling and interaction handling (both tap and long-press gestures), and more

License

Notifications You must be signed in to change notification settings

fffonoff/RichTextLabel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RichTextLabel

Subclass of UILabel that simplifies work with rich text, providing Markup processing, custom links styling and interaction handling (both tap and long-press gestures), and more

Requirements

‎ UIKit: iOS 12+ ‎ ‎ SwiftUI: iOS 14+ ‎ ‎ XCode 14+ ‎

Installation

CocoaPods

Add to a target's pods in your Podfile:

pod 'RichTextLabel', :git => 'https://github.com/fffonoff/RichTextLabel.git', :tag => '0.1.0'

In case if DTTextWithHtmlProcessor with its DTCoreText dependency, is not required, use Core subspec:

pod 'RichTextLabel/Core', :git => 'https://github.com/fffonoff/RichTextLabel.git', :tag => '0.1.0'

Swift Package Manager

Go to File → Add Package Dependencies… and search for Repository URL. RichTextLabel package comes with two targets, choose either of those (but not both):

How to add RichTextLabel as a dependency in your Package.swift file:

dependencies: [
    .package(url: "https://github.com/fffonoff/RichTextLabel.git", .upToNextMinor(from: "0.1.0"))
],
targets: [
    .target(
        name: "<Target_Name>",
        dependencies: [
            .product(name: "<RichTextLabel or RichTextLabelDT>", package: "RichTextLabel")
        ]
    )
]

How to use

In addition to UILabel's standard properties, following were introduced:

Attribute Default value Commentary
lineHeightMultiplier 1.0
textProcessor PlainTextProcessor() also can be set as a constructor parameter. more in Text Processors
Links styling
linkTextColor UIColor.link to use textColor for links, set it to nil
linkUnderlineStyle NSUnderlineStyle.single           to remove links underline completely, set to []
isPersistentLinkUnderline true toggle links underline visibility: always or on touch
linkHighlightColor UIColor(hex: #ADD9E659)  by default, links are highlighted on touch. to disable, set to nil
linkHighlightCornerRadius 6
Links interaction
linkTapAction nil all other gestures, except scroll or panning, are ignored in the links area
linkLongPressAction nil
linkLongPressDuration TimeInterval(0.5)

⚠️  adjustsFontSizeToFitWidth functionality is not supported yet

UIKit

Since RichTextLabel is a subclass of UILabel, its configuration mostly remains the same, with additional customization done through the properties listed above. The recommended approach is to set the text using text property, which will be processed into attributedText under the hood using textProcessor. Alternatively, you can set the attributedText property yourself, and it will be decorated. However, note that link detection won't be applied automatically; you need to handle it yourself. This method might be useful if you prefer to manually set up NSAttributedString.Key.link attributes

Example of use
import RichTextLabel

// standard UILabel-like setup
let textLabel = RichTextLabel(textProcessor: TextWithHtmlProcessor()) // textProcessor parameter can be omitted
textLabel.numberOfLines = 0
textLabel.font = .preferredFont(forTextStyle: .body)
textLabel.textColor = .white

// additional configuration using new properties
textLabel.lineHeightMultiplier = 1.15
textLabel.linkTextColor = .systemOrange
textLabel.linkHighlightColor = .lightText
textLabel.isPersistentLinkUnderline = false
textLabel.linkTapAction = { url in
    // link tap handling
}
textLabel.linkLongPressAction = { url in
    // link long-press handling
}

textLabel.text = "Rich text with links: <a href=\"https://github.com/fffonoff/RichTextLabel\">Some link</a>"

SwiftUI

RichTextLabel comes with a SwiftUI wrapper view, RichText. It hosts UIViewRepresentable for RichTextLabel and is responsible for its sizing in iOS 14-15

Example of use
import RichTextLabel

RichText(
    "Rich text with links: <a href=\"https://github.com/fffonoff/RichTextLabel\">Some link</a>",
    // following parameters all can be omitted
    textProcessor: TextWithHtmlProcessor(),
    configure: { richText in
        richText.font = .systemFont(ofSize: 27)
        richText.textColor = .white
        richText.textAlignment = .justified
        richText.lineHeightMultiplier = 1.25
        richText.linkTextColor = .systemOrange
        richText.linkHighlightColor = .white
        richText.linkUnderlineStyle = []
    },
    linkTapAction: { url in
        // link tap handling
    },
    linkLongPressAction: { url in
        // link long-press handling
    }
)

SwiftUI view modifiers

So far, only .lineLimit() view modifier can be used for text styling. Others, such as .multilineTextAlignment() and .truncationMode(), offer fewer options compared to their counterparts in UIKit, and the rest don't have an option for bridging yet

Text Processors

Text processor is responsible for creation of NSAttributesString from the text in text property and updating its attributes

Text processor Markup support Description
PlainTextProcessor No Default text processor, provides automatic links detection
TextWithHtmlProcessor HTML Uses system HTML reader
DTTextWithHtmlProcessor HTML Uses DTCoreText HTML reader (more stable and efficient than the system one)

DTTextWithHtmlProcessor

DTTextWithHtmlProcessor relies on DTCoreText, which itself depends on another library, DTFoundation. In result, it's 2 extra dependencies, not to mention warnings, since both libraries are old. If you don't need it, refer to the Installation section for instructions on installing RichTextLabel without it

To-Do

  • built-in Markdown text processor
  • adjustsFontSizeToFitWidth support
  • implement custom underline drawing
  • textContainerInset configuration similar to UITextView
  • optimize further and remove UILabel inheritance
  • utilize NSTextLayoutManager

About

Subclass of UILabel that simplifies work with rich text, providing Markup processing, custom links styling and interaction handling (both tap and long-press gestures), and more

Topics

Resources

License

Stars

Watchers

Forks