【问题标题】:SwiftUI TextField onChange not triggeredSwiftUI TextField onChange 未触发
【发布时间】:2021-12-01 07:19:28
【问题描述】:

刚接触 SwiftUI 并试图解决问题。 我正在实现一个条形码扫描仪,它由 TextFieldButtonCameraView 组成。 CameraView 将扫描条码,在TextField 中显示序列号,Button 将使用序列号与蓝牙设备配对。

所以现在在我的 SwiftUI 类中,我的 UI 设置如下:

struct BTLEConnectionView: View {
    @ObservedObject var bluetoothConnectorViewModel: BluetoothConnectorViewModel
    @ObservedObject var barcodeScannerViewModel = BarcodeScannerViewModel()
    @Binding var deviceID: String

    @State private var serialNumber: String = ""

    var body: some View {
        VStack {
           HStack {
               DeviceIDTextField(deviceID: $deviceID, serialNumber: $serialNumber, viewModel: barcodeScannerViewModel)
            
               PairButton(bluetoothConnectorViewModel: bluetoothConnectorViewModel, barcodeScannerViewModel: barcodeScannerViewModel, serialNumber: $serialNumber)
           }
           .padding()
    
           BarcodeScannerView(barscannerViewModel: barcodeScannerViewModel)
       }
   }
}

struct DeviceIDTextField: View {
   @Binding var deviceID: String
   @Binding var serialNumber: String
   @ObservedObject var viewModel: BarcodeScannerViewModel

   var body: some View {
       let serialNumberBinding = Binding<String>(
           get: { viewModel.barcodeString.isEmpty ? serialNumber : viewModel.barcodeString },
           set: { serialNumber = viewModel.barcodeString.isEmpty ? $0 : viewModel.barcodeString }
       )
    
       TextField(NSLocalizedString("textfield.hint.device.id", comment: ""), text: serialNumberBinding)
           .textFieldStyle(RoundedBorderTextFieldStyle())
           .onChange(of: serialNumber, perform: { value in
               serialNumber = value
           })
   }

   private func textFieldChanged(_ text: String) {
       print(text)
   }
}

struct PairButton: View {
   @ObservedObject var bluetoothConnectorViewModel: BluetoothConnectorViewModel
   @ObservedObject var barcodeScannerViewModel: BarcodeScannerViewModel
   @Binding var serialNumber: String

   var body: some View {
       Button(action: {
           withAnimation {
               bluetoothConnectorViewModel.connectBluetoothLowEnergyDevice(deviceID: serialNumber)
           }
       }) {
           ButtonText(text: NSLocalizedString("button.text.pair", comment: ""))
       }
   }
}

所以基本上我想这样做: 如果用户扫描条形码,则序列号被添加到文本字段中,按下配对按钮以使用该序列号并调用该方法并传入序列号。 如果用户删除预填充的序列号,输入自己的序列号,它应该更新文本字段,按下按钮应该使用新的序列号。

现在,当我扫描条形码时,它会填充文本字段,但是直到我实际输入 TextField 时才会调用 onChange 回调,因此永远不会为方法调用设置结果。

对此的任何帮助都会很棒,希望它有意义。

【问题讨论】:

    标签: ios swift swiftui textfield


    【解决方案1】:

    您可以使用自定义闭包创建绑定,如下所示:

    struct ContentView: View {
        @State var location: String = ""
    
        var body: some View {
            let binding = Binding<String>(get: {
                self.location
            }, set: {
                self.location = $0
                // do whatever you want here
            })
    
            return VStack {
                Text("Current location: \(location)")
                TextField("Search Location", text: binding)
            }
    
        }
    }
    

    【讨论】:

    • 感谢您的帖子,但我认为它不能解决我所问的问题。现在在 set self.serialNumber = $0 serialNumber = viewModel.barcodeString.isEmpty ? $0 : viewModel.barcodeString 不起作用。我需要将它设置为 viewModel 的任何内容,如果用户键入,删除 viewModel 字符串并使用正在键入的任何内容
    • 当屏幕打开时,TextField 会显示提示文本。如果用户扫描条形码,它应该被填充到 TextField 中,而现在它没有。 viewModel 包含很好的扫描值,但是我不知道如何让它在 TextField 中正确使用它
    猜你喜欢
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多