如何检测TextField/TextEditor中用户换行并自动添加列表符号?
实现TextEditor回车自动添加列表符号
要实现这个效果,SwiftUI原生的TextEditor自带回调搞不定,得用它底层的UITextView来做核心处理:
- 自定义一个包装UITextView的View,实现
UIViewRepresentable协议 - 在
UITextViewDelegate的textView(_:shouldChangeTextIn:replacementText:)方法里检测换行符 - 当用户按下回车时,自动在新行开头插入
-
以下是完整代码示例:
import SwiftUI struct ListTextEditor: UIViewRepresentable { @Binding var text: String func makeUIView(context: Context) -> UITextView { let textView = UITextView() textView.delegate = context.coordinator textView.font = UIFont.systemFont(ofSize: 16) return textView } func updateUIView(_ uiView: UITextView, context: Context) { if uiView.text != text { uiView.text = text } } func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, UITextViewDelegate { var parent: ListTextEditor init(_ parent: ListTextEditor) { self.parent = parent } func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { // 检测是否是换行按键 if text == "\n" { let currentText = textView.text ?? "" let startIndex = currentText.index(currentText.startIndex, offsetBy: range.location) let beforeText = currentText[..<startIndex] // 判断当前是否处于新行开头 if beforeText.isEmpty || beforeText.last == "\n" { // 插入换行+列表符号 let newText = currentText.replacingCharacters(in: range, with: "\n- ") parent.text = newText // 把光标移到列表符号后面,保证输入流畅 let newCursorPosition = NSRange(location: range.location + 3, length: 0) textView.selectedRange = newCursorPosition return false // 自己处理文本替换,跳过系统默认操作 } } // 其他按键操作正常处理,同步更新绑定文本 let newText = (textView.text ?? "").replacingCharacters(in: range, with: text) parent.text = newText return true } } } // 使用示例 struct ContentView: View { @State private var editorText = "- " var body: some View { ListTextEditor(text: $editorText) .padding() .frame(minHeight: 300) .border(Color.gray.opacity(0.3)) } }
关键细节说明:
- 用
UIViewRepresentable封装UITextView,才能拿到底层的代理回调来监听按键事件 - 拦截换行符后,判断当前是否是新行开头,避免在一行中间换行时错误添加列表符号
- 手动调整光标位置到
-后面,让用户可以直接继续输入内容,体验更顺畅 - 初始文本设为
-,可以让用户打开编辑器就处于列表输入状态
这样用户每次按下回车,新行都会自动带上- ,和Word的自动列表效果完全一致。
内容的提问来源于stack exchange,提问作者The_B3Ni
相关产品推荐
相关产品推荐

