在 SwiftUI TextEditor 中设置光标位置

Posted

技术标签:

【中文标题】在 SwiftUI TextEditor 中设置光标位置【英文标题】:Setting the cursor position within a SwiftUI TextEditor 【发布时间】:2020-12-19 23:22:14 【问题描述】:

有没有办法以编程方式将光标移动到特定的文本行或在 SwifUI TextEditor 中选择它?

例如,如果有一个TextEditor,其中写有 10 行。 当用户按下按钮时,光标会导航到第 3 行,否则文本会被选中。

【问题讨论】:

你对文本行的定义是什么? 就像代码行一样,每个文本直到换行。例如swift:2:1: 表示第一个换行符之后的行。 好的。您将我们指向一个网站并说它是针对UITextField 的。那么这个关于 Cocoa 或 SwiftUI 中的 NSTextFieldNSTextView 的问题? 很抱歉,如果这具有误导性,该链接只是为了让更多人了解我设置光标位置的意思。但我要求的是在 SwiftUI TextEditor 中执行此操作,就像 NSTextView,如果这就是您的意思。我正在考虑包装一个 NSTextView 以在 SwiftUI 中使用,而不是新的 TextEditor,但我不知道这是否是唯一的解决方案。 我会删除关于UITextField的声明,这与您的问题不太相关。 【参考方案1】:

目前无法使用默认的 SwiftUI TextEditor。您可以通过将NSTextField(/UITextField) 包装在NSViewRepresentable(/UIViewRepresentable) 中来实现所需的行为。

我最近为CodeEditor 实现了这个。你可以在那里查看实现(尤其是changes from my PR)。

但是,由于您在其中一个 cmets 中提到了代码,您可能还只想将 CodeEditor 用作一个整体。

通过我的实现,您可以为编辑器提供与Range<String.Index> 的绑定。

 struct ContentView: View 
    static private let initialSource = "let a = 42\n"

    @State private var source = Self.initialSource
    @State private var selection = Self.initialSource.endIndex..<Self.initialSource.endIndex

    var body: some View 
        CodeEditor(source: $source,
                   selection: $selection,
                   language: .swift,
                   theme: .ocean,
                   autoscroll: true)
        Button("Select All") 
            selection = source.startIndex..<source.endIndex
        
    

您可以通过更新selection 来移动光标。如果范围为“空”,则只需将光标移动到起始索引。否则,从开始(包含)到结束索引(排除)的字符将被选中。

here 提供的解决方案应该可以让您找到正确的String.Index 来放置光标所在的行。

如果要选择整行,请从这个String.Index 开始双向扫描字符串,直到找到换行符为止。

【讨论】:

以上是关于在 SwiftUI TextEditor 中设置光标位置的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 4.0 如何轻松在 iOS 16 中设置 TextEditor 背景色

SwiftUI 4.0 如何轻松在 iOS 16 中设置 TextEditor 背景色

在 SwiftUI 中控制 TextEditor 的大小

为啥我在 SwiftUI 中的 TextEditor 会忽略我的 .keyboardType?

在 SwiftUI 中,为啥 Spacer 会将文本推送到 TextEditor 框架之外?

如何在 SwiftUI TextEditor 中获取用户选择的文本