如何从SwiftUI中UITextView的UIViewRepresentable委托方法中获取选定范围

kmbjn2e3  于 2022-10-31  发布在  Swift
关注(0)|答案(1)|浏览(187)

我有一个代码,我需要从(func textViewDidChangeSelection)到ContentView的TextView的选定范围。我如何在SwiftUI中做这样的事情?
这是我代码的基本思想。

struct ContentView: View {
    @State private var text = ""

    var body: some View {
        UITextViewRepresentable(text: $text)
    }
}

struct UITextViewRepresentable: UIViewRepresentable {
    let textView = UITextView()
    @Binding var text: String

    func makeUIView(context: Context) -> UITextView {
        textView.delegate = context.coordinator
        return textView
    }

    func updateUIView(_ uiView: UITextView, context: Context) {
        // SwiftUI -> UIKit
        uiView.text = text
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(text: $text)
    }

    class Coordinator: NSObject, UITextViewDelegate {
        @Binding var text: String

        init(text: Binding<String>) {
            self._text = text
        }

        func textViewDidChange(_ textView: UITextView) {
            // UIKit -> SwiftUI
            _text.wrappedValue = textView.text
        }

        func textViewDidChangeSelection(_ textView: UITextView) {
            // Fires off every time the user changes the selection.
            print(textView.selectedRange)
        }
    }
}
xiozqbni

xiozqbni1#

只需为它添加一个NSRange类型的额外绑定,因为它是textView.selectedRange的类型。
这意味着在UIViewRepresentable上加1:

struct UITextViewRepresentable: UIViewRepresentable {
    let textView = UITextView()
    @Binding var text: String
    @Binding var range: NSRange // <---

和一个给协调器:

func makeCoordinator() -> Coordinator {
    Coordinator(text: $text, range: $range) // <---
}

class Coordinator: NSObject, UITextViewDelegate {
    @Binding var text: String
    @Binding var range: NSRange // <---

    init(text: Binding<String>, range: Binding<NSRange>) {
        _text = text
        _range = range
    }

    // ...

    func textViewDidChangeSelection(_ textView: UITextView) {
        range = textView.selectedRange
    }

现在在ContentView中,可以将其作为@State

@State private var text = ""
@State private var range = NSRange()

var body: some View {
    UITextViewRepresentable(text: $text, range: $range)
}

相关问题