How to select text with TextSelection in SwiftUI | SwiftUI Bootcamp #56
By default, Text views in SwiftUI are not selectable — users can read them but cannot copy their content. This matters in detail screens, article views, order confirmation pages, and anywhere users might want to copy an address, order number, or code snippet. iOS 15 introduced .textSelection(.enabled) as a one-line fix. After this lesson you'll understand what it enables, where to place it, and when selectability is important for your users.
What You'll Learn
- How
.textSelection(.enabled)makes aTextview's content copyable by the user - How to apply the modifier to a container to enable selection on all descendant
Textviews at once - The difference between
.textSelection(.enabled)and.textSelection(.disabled) - When text selectability matters from an accessibility and user experience perspective
Mental Model
Think of a Text view's default state as text printed on a poster. You can read it, but you can't tear a piece off and take it with you. Adding .textSelection(.enabled) is like printing the same text in a book instead — now you can highlight it, copy it, and use it elsewhere.
SwiftUI propagates this modifier through the view hierarchy just like .foregroundColor or .font. If you apply .textSelection(.enabled) to a VStack containing ten Text views, all ten become selectable. Conversely, .textSelection(.disabled) on an individual child view inside that VStack removes selectability from just that one text element — useful for decorative or sensitive content you explicitly don't want copied.
Detailed Explanation
.textSelection() takes a TextSelectability value — either .enabled or .disabled. It was introduced in iOS 15 alongside other quality-of-life improvements for text-heavy interfaces. Before iOS 15, making static Text content selectable required switching to TextField (which allows editing, not just selection) or wrapping content in a UIViewRepresentable.
When selectability is enabled, users long-press the Text view to reveal the standard iOS text selection handles and the system contextual menu offering "Copy", "Look Up", and "Share". The selection UI is entirely native — you don't implement any of it. The modifier simply unlocks this system behavior.
The modifier cascades: apply it to a parent view and all child Text views inherit the setting. This makes it efficient to enable selection across an entire article view, settings panel, or detail card with one modifier rather than modifying each individual Text.
When to enable text selection: order confirmation numbers, tracking codes, addresses, email addresses, phone numbers, code snippets, legal texts where users might want to research specific terms, and any content a user might reasonably want to copy for use in another app. When NOT to enable it: navigation labels, button labels, tab bar items, marketing headlines, and any text that is purely decorative — unnecessary selectability can make the UI feel unpolished.
Code Structure
TextSelectionBootcamp.swift is intentionally minimal. It demonstrates the core API with a single Text view and the .textSelection(.enabled) modifier. The real-world value comes from understanding how and where to apply it in larger view hierarchies — which the detailed explanation and walkthrough cover.
Complete Code
TextSelectionBootcamp.swift
import SwiftUI
struct TextSelectionBootcamp: View {
var body: some View {
Text("Hello, World!")
.textSelection(.enabled) // enables the long-press selection UI and the system Copy/Share menu on this Text
}
}
struct TextSelectionBootcamp_Previews: PreviewProvider {
static var previews: some View {
TextSelectionBootcamp()
}
}Code Walkthrough
Text("Hello, World!")— A standard staticTextview. Without the modifier below, long-pressing this text does nothing — the system selection UI does not appear..textSelection(.enabled)— This single modifier unlocks the system text selection behavior for the view. On iOS, it activates the long-press gesture recognizer that shows selection handles and the contextual "Copy" / "Look Up" / "Share" menu. On macOS, it allows click-drag selection and keyboard shortcuts (Cmd+A, Cmd+C).Cascade behavior (not shown in code but important) — In a real app you would more likely write:
swiftVStack { Text("Order #: 12345-ABC") Text("Tracking: TK998877-XYZ") } .textSelection(.enabled) // both Text views become selectableApplying the modifier to the container is more maintainable than adding it to each individual
Text..textSelection(.disabled)— The inverse. Use this inside a container that has.textSelection(.enabled)to opt specific children out of selectability:swiftVStack { Text("Selectable content").textSelection(.enabled) Text("Decorative label").textSelection(.disabled) }Preview testing — To verify text selection works, run the app on a device or simulator. Long-press the text — the selection handles should appear. Tap "Copy" and paste into another app to confirm. Text selection does not activate in Xcode's static canvas preview.
Common Mistakes
Mistake: Applying .textSelection(.enabled) to a TextField or TextEditorTextField and TextEditor are already editable (and therefore selectable) by design — adding .textSelection(.enabled) has no additional effect and can cause confusion about intent. The modifier is specifically for read-only Text views.
Mistake: Enabling text selection on button labels, navigation titles, or tab items.textSelection(.enabled) on a Button label can interfere with the button's tap recognition. Navigation titles and tab items use their own text rendering that is not affected by this modifier. Apply it only to static display Text views in content areas, not interactive control labels.
Mistake: Forgetting that .textSelection is iOS 15+ only, and not adding availability checks in apps supporting earlier OS versions
If your app targets iOS 14 or earlier and you call .textSelection(.enabled), the compiler will produce a warning (or error with strict availability settings). Wrap the modifier in an @available(iOS 15, *) check or raise your deployment target to iOS 15.
Key Takeaways
.textSelection(.enabled)makes aTextview's content selectable by the user via the standard iOS long-press + copy UI — a one-line addition that significantly improves usability for content users might want to share or use elsewhere.- Apply the modifier to a container view to enable selection on all descendant
Textviews at once; use.textSelection(.disabled)on individual children to exclude specific decorative texts. - Enable text selection for user-facing data like order numbers, codes, addresses, and article content; leave it disabled (the default) for navigational labels and decorative copy.
Last updated: June 27, 2026