Represents a selection of attributed text.
A selection is either an insertion point (e.g. a cursor in the text), or
spans over a range of characters. While that range is always visually
contiguous, it may not be logically contiguous in the text storage.
Specifically, a single selection value cannot represent multiple cursors.
This is frequently used to represent selection of text in a `TextEditor`.
The following example shows a text editor that leverages text selection to
offer live suggestions based on the current selection.
struct SuggestionTextEditor: View {
@State var text: AttributedString = ""
@State var selection = AttributedTextSelection()
var body: some View {
VStack {
TextEditor(text: $text, selection: $selection)
// A helper view that offers live suggestions based on selection.
SuggestionsView(substrings: getSubstrings(
text: text, indices: selection.indices(in: text))
}
}
private func getSubstrings(
text: String, indices: AttributedTextSelection.Indices
) -> [Substring] {
// Resolve substrings representing the current selection...
}
}
struct SuggestionsView: View { ... }
You can also use the ``View/textSelectionAffinity(_:)`` modifier to specify
a selection affinity on the given hierarchy:
struct SuggestionTextEditor: View {
@State var text: AttributedString = ""
@State var selection = AttributedTextSelection()
var body: some View {
VStack {
TextEditor(text: $text, selection: $selection)
// A helper view that offers live suggestions based on selection.
SuggestionsView(substrings: getSubstrings(
text: text, indices: selection.indices(in: text))
}
.textSelectionAffinity(.upstream)
}
private func getSubstrings(
text: String, indices: AttributedTextSelection.Indices
) -> [Substring] {
// Resolve substrings representing the current selection...
}
}
struct SuggestionsView: View { ... }
- SeeAlso: ``TextSelectionAffinity``, ``TextEditor``
Obtain a lazy sequence of all attribute values the selection has in a
given text.
The attribute values of a selection are the attribute values of each run
that is fully or partially selected, or the typing attributes in the
case the selection is an insertion point.
By default, the sequence contains the attribute container for every
run or the typing attributes. Use the ``Attributes``' subscript to
obtain only the values for a single attribute:
selection.attributes(in: text)[\.foregroundColor].contains(.red)
Initialize a selection to a single insertion point.
- Parameter insertionPoint: The index of the string where the
charet should be positioned.
- Parameter typingAttributes: The attributes for the next character
that is typed, or `nil` if they should be inferred from the attributes
on the text.
Returns the typing attributes for a corresponding text.
The typing attributes are the attributes that will be applied to any new
characters typed out by the user.
- Note: The returned container may contain values for attributes that
specify <doc://com.apple.documentation/documentation/Foundation/AttributedStringKey/runBoundaries>
and thus might not actually get applied to new content.
The current text selection indices.
Always make sure to keep selection and text synchronized. Use
``Foundation/AttributedString/transform(updating:body:)``,
``Foundation/AttributedString/transformAttributes(in:body:)`` or
``Foundation/AttributedString/replaceSelection(_:with:)`` to do so
automatically.
Reset your selection manually to a newly initialized one after making
programmatic changes to the text where the selection should not just
move with the characters.
struct ContentView: View {
@State private var text = AttributedString()
@State private var selection = AttributedTextSelection()
var body: some View {
TextEditor(text: $text, selection: $selection)
Button("Insert Date") {
text.replaceSelection(
&selection,
withCharacters: Date.now.formatted())
}
Button("Reset") {
text = "Hello, World!"
selection = .init(range: text.startIndex..<text.endIndex)
}
}
}
For more details on attributed string index validity, see
<doc://com.apple.documentation/documentation/Foundation/AttributedString/Index/isValid(within:)-8fw50>.
- Returns: The current selection if valid for the given `text` or a
valid fallback index otherwise.