我想回应键盘按键在UITextField包装成UIViewRepresentable.下面是包装器视图的代码:

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相关问答推荐

当我点击模拟器中的文本字段时,UIKit CLLocationButton崩溃

如何在SWIFT中轻松格式化公制和英制使用的UnitVolume

Swift C外部实现的Task / Future类类型

关闭 SwiftUI TabView 中的子视图

如何使用模型在 SwiftUI 的列表中进行搜索

有没有办法让文本字段以不同的 colored颜色 显示而不影响半透明背景?

如何使一个 Reality Composer 场景中的分组对象可拖动?

为什么在Swift中每次调用Decimal类型的formatted()方法都会越来越慢?

Swift-SceneKit-无法从art.scnassets加载.scn文件

如何自己实现同一个 iOS 16 锁屏圆形小部件?

类型 '()' 不能符合 View (除非它肯定是 View,这次没有恶作剧)

在 SwiftUI 中操作绑定变量

无法增加系统镜像的大小

SwiftUI 文本被意外截断

Swift 2.0 方法不能标记为@objc,因为参数的类型不能在 Objective-C 中表示

如何快速判断设备方向是横向还是横向?

在 Swift 中获取双精度的小数部分

3D touch /强制touch 实现

Swift 3:日期与 NSDate?

使用 swift IOS 使 UIBarButtonItem 消失