⌨️

【SwiftUI】TextFieldの選択状態をTextSelectionで取得

2024/08/21に公開

TextSelection

TextFieldTextEditor)で、ユーザーが選択したテキストを操作したり管理する方法が追加されました。(SecureFieldはサポート無さそう)

新しく追加されたTextSelectionTextFieldでの選択状態をプログラムからアクセスできるようになります。

public struct TextSelection : Equatable, Hashable { ... }

使い方

TextFieldのイニシャライザにselection: Binding<TextSelection>を渡すことで、ダブルタップ等で選択したテキストの範囲等が含まれるTextSelectionを取得できます。

ドキュメント:init(_:text:selection:prompt:axis:)

@State private var text = ""
@State private var selection: TextSelection?

var body: some View {
    VStack {
        TextField("name", text: $text, selection: $selection)

        TextEditor(text: $text, selection: $selection)
    }
}

TextEditor での使用

同様に、TextEditor でも選択状態を管理できます。

TextEditor(text: $text, selection: $selection)

サンプル

選択されたテキスト(selectedText)を取得するには、TextSelection.Indices経由で取得します。

struct SimpleTextEditor: View {
    @State private var text: String = ""
    @State private var selection: TextSelection?

    var body: some View {
        VStack {
            TextField("name", text: $text, selection: $selection)

            if let selection,
               let selectedText = getSelectedText(selection: selection) {
                Text("Selected Text: \(selectedText)")
            }
        }
    }

    private func getSelectedText(selection: TextSelection) -> String? {
        switch selection.indices {
        case .selection(let range):
            return String(text[range])
        case .multiSelection(let rangeSet):
            let selected = rangeSet.ranges.map { String(text[$0]) }.joined(separator: ", ")
            return selected.isEmpty ? nil : selected
        }
    }
}

参考リンク

https://youtu.be/CNMRV0F0w74?si=McLf_sA_Ur5iAa5S&t=901
https://developer.apple.com/documentation/swiftui/textselection

Discussion