+
Skip to content

A supplementary TextView for SwiftUI that provides better text selection experience, as well as enabling native view embedding using declarative syntax

License

Notifications You must be signed in to change notification settings

LiYanan2004/RichText

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

71 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RichText

A supplementary TextView for SwiftUI that provides better text selection experience, as well as enabling native view embedding using declarative syntax.

Powered by TextKit 2.

Requirements

  • Xcode 26.0+
  • iOS 17.0+
  • macOS 14.0+

Documentation

You can view documentation on:

Getting Started

Add RichText as a dependency in your Swift Package Manager manifest.

.package(url: "https://github.com/LiYanan2004/RichText.git", branch: "main"),

Include RichText in any targets that need it.

.target(
    name: "MyTarget",
    dependencies: [
        .product(name: "RichText", package: "RichText"),
    ]
),

Plain String & Attributed String

TextView provides a result builder that accepts both plain string and AttributedString.

let packageName: AttributedString = {
    var value = AttributedString("RichText")
    value.foregroundColor = .blue
    value.font = .headline
    return value
}()

TextView {
    "Hello, "
    packageName
    "!"
}

Inline SwiftUI Views

You can embed SwiftUI view along with other text as well, while preserving text selection capability.

RichText will try to extract SwiftUI.Text content and convert it into AttributedString. If that fails, a plain string will be used instead.

TextView {
    Text("Hi, This is **RichText**.")
}

Other SwiftUI views are added as an individual text element, which means text selection will either include or exclude the entire view.

TextView {
    "Tap the"
    Space()
    Button("button") {
        print("Button Clicked")
    }
    Space()
    "to continue."
}

TextView {
    "Rating: "
    
    // The whole `HStack` will be either selected or de-selected.
    HStack(spacing: 2) {
        ForEach(0..<5) { _ in
            Image(systemName: "star.fill")
                .foregroundStyle(.yellow)
        }
    }
}

Dynamic Views

If the embeded view contains its own state, you will need to provide a unique view identifier using .id(_:) to bind the view's identity, otherwise, its state will be reset whenever the textContent is recomputed.

In the following example, the state of the globe icon will get reset when ContentView.body gets re-computed without explicit id specified.

Tip

You may need to add .id(_:) view modifier directly under embeded view.

Currently, .id(_:) inside View.Body is not recognizable.

struct ContentView: View {
    @State private var isOpaque: Bool = true
   
    var body: some View {
        VStack {
            Toggle("Opaque", isOn: $isOpaque)
            TextView {
                "Hello "
                ColorfulGlobeIcon()
                    .id("globe-icon") // Explicitly bind the identity here.
                " World"
            }
            .opacity(isOpaque ? 1 : 0.5)
        }
    }
}

struct ColorfulGlobeIcon: View {
    @State var color: Color = .random
    
    var body: some View {
        Image(systemName: "globe")
            .foregroundStyle(color)
            .onTapGesture { 
                color = .random
            }
            .id("globe-icon") // ❌ This does NOT bind the identity of the view internally
    }
}

Troubleshooting

SwiftUI Font is only reflected on OS 26+

SwiftUI.Font.Resolved is only available on OS 26+. We use that to convert a Font into PlatformFont.

If you need to customize font on older OS version, use PlatformFont explicitly.

TextView("TextView")
    .font(UIFont.systemFont(ofSize: 28)) // This would work consistently across OS versions.

About

A supplementary TextView for SwiftUI that provides better text selection experience, as well as enabling native view embedding using declarative syntax

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

No packages published

Languages

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载