swift - 响应 UITextField (UIViewRepresentable) 中的特定按键

标签 swift swiftui uitextfield uitextfielddelegate

我想在包装为 UIViewRepresentableUITextField 中响应键盘按下。这是包装 View 的代码:

import SwiftUI
import UIKit

struct ContentView: View {
    @State var text: String = "Hello."
    
    var body: some View {
        WrappedUITextField(text: $text)
    }
}

struct WrappedUITextField: UIViewRepresentable {
    @Binding var text: String
    
    func makeCoordinator() -> Coordinator {
        Coordinator($text)
    }
    
    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField()
        textField.delegate = context.coordinator
        textField.text = text
        textField.autocapitalizationType = .none
        return textField
    }
    
    func updateUIView(_ uiView: UITextField, context: Context) {
        if text != context.coordinator.currentText { uiView.text = text }
    }
}

class Coordinator: NSObject, UITextFieldDelegate {
    
    var text: Binding<String>
    var currentText: String
    
    init(_ text: Binding<String>) {
        self.text = text
        currentText = text.wrappedValue
    }
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        
        guard let oldText = textField.text,
              let textRange = Range(range, in: oldText) else {
            return false
        }
        
        self.currentText = oldText.replacingCharacters(in: textRange, with: string)
        print("oldText = \"\(oldText)\", new text = \"\(currentText)\"")
        
        self.text.wrappedValue = currentText
        return true
    }
    
    func textFieldDidChangeSelection(_ textField: UITextField) {
        print("textFieldDidChangeSelection")
    }
}

具体来说,我想在光标位于左/最右边缘时按左/右箭头键时触发一些操作,例如“|abc”,其中“|”是光标位置,用户按下向左箭头。

UITextFieldDelegate 方法在这里不起作用,因为当光标已经位于左/右边缘(分别)时按左/右箭头键不会更改文本内容(例如, textFieldDidBeginEditing() 不会被调用),也不会调用光标位置(例如,textFieldDidChangeSelection() 不会被调用)。

在这种情况下我该如何响应左/右箭头键?像 pressesBegan() 方法这样的东西在这里会很好,但我不知道如何将其与 UIViewRepresentable 集成(例如,添加 override func pressesBegan( ...)Coordinator 不起作用)。

谢谢

最佳答案

只需创建继承 UITextField 的类并覆盖其中的处理程序

func makeUIView(context: Context) -> UITextField {
    let textField = MyTextField()                   // << here !!
    textField.delegate = context.coordinator
    textField.text = text
    textField.autocapitalizationType = .none
    return textField
}

class MyTextField: UITextField {
   override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
       // handle here requried events

       // call super if not handled above
       super.pressesBegan(presses, with: event)
   }
}

关于swift - 响应 UITextField (UIViewRepresentable) 中的特定按键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73257525/

相关文章:

ios - 在 Swift 中对 UITextField 中的每个数字求和

ios - 如何限制 UITextField 中除点和下划线以外的特殊字符?

Swift struct 相当于 C++ 可变关键字?

ios - 使用 alamofire 在 swift 中创建字典

swift - 在 swiftUI 的后台继续运行计时器

SwiftUI http 请求

ios - Swift:如何等待事件然后切换 View ?

swift - 访问 XCUIElement 中的最后一个元素

swift - 如何在主体 View 中设置对齐方式?

ios - 自定义委托(delegate) nil 且不保存 userDefaults