TextEditor in SwiftUI still doesn’t have any API to get user selection. But since it’s using NSTextView internally we can subscribe to its notifications.
Here’s an example of getting a substring from user selection:
import SwiftUI
struct ContentView: View {
@State var myString = "Hello world"
@State var selectedString = ""
var body: some View {
HStack {
Text("Selection:")
.foregroundStyle(.secondary)
Text("\"\(selectedString)\"")
}.padding()
TextEditor(text: $myString)
.font(.title)
.onReceive(NotificationCenter.default.publisher(
for: NSTextView.didChangeSelectionNotification
), perform: { notification in
guard let textView = notification.object as? NSTextView else { return }
// check, if it's the one we need
guard textView.string == myString else { return }
let selectionRage = textView.selectedRange()
let start = String.Index(
utf16Offset: selectionRage.lowerBound, in: myString
)
let end = String.Index(
utf16Offset: selectionRage.upperBound, in: myString
)
let subStringRange: Range<String.Index> = start..<end
selectedString = String(myString[subStringRange])
})
}
}