SwiftUI中如何在TextField光标当前位置插入字符串?
在SwiftUI的TextField光标位置插入字符串
SwiftUI原生TextField没有直接暴露光标位置的API,要实现光标处插入字符,需要借助UIKit的UITextField封装自定义组件,跟踪光标位置并完成插入逻辑。
步骤1:封装带光标跟踪的自定义TextField
创建UIViewRepresentable组件包装UITextField,对外暴露文本、光标位置的绑定,同时同步文本变化与光标移动状态:
import SwiftUI struct CursorTextField: UIViewRepresentable { @Binding var text: String @Binding var selectedRange: NSRange var placeholder: String func makeUIView(context: Context) -> UITextField { let textField = UITextField() textField.placeholder = placeholder textField.delegate = context.coordinator textField.addTarget(context.coordinator, action: #selector(Coordinator.textChanged), for: .editingChanged) return textField } func updateUIView(_ uiView: UITextField, context: Context) { // 避免循环更新:仅当文本不一致时同步 if uiView.text != text { uiView.text = text } // 同步光标位置 guard let startPos = uiView.position(from: uiView.beginningOfDocument, offset: selectedRange.location), let endPos = uiView.position(from: startPos, offset: selectedRange.length) else { return } uiView.selectedTextRange = uiView.textRange(from: startPos, to: endPos) } func makeCoordinator() -> Coordinator { Coordinator(parent: self) } class Coordinator: NSObject, UITextFieldDelegate { var parent: CursorTextField init(parent: CursorTextField) { self.parent = parent } @objc func textChanged(_ textField: UITextField) { parent.text = textField.text ?? "" updateCursorRange(textField) } func textFieldDidChangeSelection(_ textField: UITextField) { updateCursorRange(textField) } private func updateCursorRange(_ textField: UITextField) { guard let selectedRange = textField.selectedTextRange else { return } let startOffset = textField.offset(from: textField.beginningOfDocument, to: selectedRange.start) let length = textField.offset(from: selectedRange.start, to: selectedRange.end) parent.selectedRange = NSRange(location: startOffset, length: length) } } }
步骤2:主View中实现插入逻辑
用@State变量存储文本和光标位置,按钮点击时根据光标位置插入字符,并更新光标到插入后的位置:
struct ContentView: View { @State private var inputText: String = "1234" @State private var cursorRange = NSRange(location: 2, length: 0) // 初始光标在"12"和"34"之间 var body: some View { VStack { CursorTextField(text: $inputText, selectedRange: $cursorRange, placeholder: "Input text") .padding() .border(.gray) .toolbar { ToolbarItemGroup(placement: .keyboard) { Button("+") { insertString(at: cursorRange.location, string: "+") } } } } .padding() } private func insertString(at location: Int, string: String) { guard location <= inputText.count else { return } // 在光标位置插入字符串 let insertIndex = inputText.index(inputText.startIndex, offsetBy: location) inputText.insert(contentsOf: string, at: insertIndex) // 更新光标到插入字符的后方 cursorRange = NSRange(location: location + string.count, length: 0) } }
关键说明
- 自定义
CursorTextField会实时同步文本内容和光标位置到SwiftUI状态变量 insertString方法负责字符插入与光标位置更新,确保操作后光标停在新字符后方- 初始光标位置可根据需求调整,示例中设置的位置点击"+"后会直接得到"12+34"
内容的提问来源于stack exchange,提问作者winner.ktw
相关产品推荐
相关产品推荐

