Ios 当所有文本字段在SwiftUI中都有值时,如何动态更新屏幕上的标签?

Ios 当所有文本字段在SwiftUI中都有值时,如何动态更新屏幕上的标签?,ios,swift,cocoa-touch,uitextfield,swiftui,Ios,Swift,Cocoa Touch,Uitextfield,Swiftui,我正在开发一个应用程序,允许用户使用两个单独的文本字段输入下注的赔率。例如,假设用户想要的几率是3/1。用户需要在一个字段中输入3,在另一个字段中输入1 我有两个状态变量: leftOddsVal 右奥德斯瓦尔 这是我在CustomTextField中使用它们的方式: CustomTextfield(text: $leftOddsVal, placeHolder: "Enter text", keyboardType: .numberPad) CustomTextfield(text: $

我正在开发一个应用程序,允许用户使用两个单独的文本字段输入下注的赔率。例如,假设用户想要的几率是3/1。用户需要在一个字段中输入3,在另一个字段中输入1

我有两个状态变量:

  • leftOddsVal
  • 右奥德斯瓦尔
这是我在CustomTextField中使用它们的方式:

CustomTextfield(text: $leftOddsVal, placeHolder: "Enter text", keyboardType: .numberPad)
CustomTextfield(text: $rightOddsVal, placeHolder: "Enter text", keyboardType: .numberPad)
CustomTextfield(text: $state, placeHolder: "Enter text", keyboardType: .numberPad)
struct CustomTextfield: UIViewRepresentable {

    @Binding var text : String
    var placeHolder: String
    var keyboardType: UIKeyboardType

    final class Coordinator: NSObject {

        var textField: CustomTextfield

        init(_ textField: CustomTextfield) {
            self.textField = textField
        }

    }

    func makeCoordinator() -> DabbleTextfield.Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> UITextField {

        let textField = UITextField()
        textField.backgroundColor = .white
        textField.placeholder = self.placeHolder
        textField.keyboardType = self.keyboardType

        return textField
    }

    func updateUIView(_ uiView: UITextField, context: Context) {

    }

}
这是自定义文本字段的代码:

CustomTextfield(text: $leftOddsVal, placeHolder: "Enter text", keyboardType: .numberPad)
CustomTextfield(text: $rightOddsVal, placeHolder: "Enter text", keyboardType: .numberPad)
CustomTextfield(text: $state, placeHolder: "Enter text", keyboardType: .numberPad)
struct CustomTextfield: UIViewRepresentable {

    @Binding var text : String
    var placeHolder: String
    var keyboardType: UIKeyboardType

    final class Coordinator: NSObject {

        var textField: CustomTextfield

        init(_ textField: CustomTextfield) {
            self.textField = textField
        }

    }

    func makeCoordinator() -> DabbleTextfield.Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> UITextField {

        let textField = UITextField()
        textField.backgroundColor = .white
        textField.placeholder = self.placeHolder
        textField.keyboardType = self.keyboardType

        return textField
    }

    func updateUIView(_ uiView: UITextField, context: Context) {

    }

}
我想做什么:

CustomTextfield(text: $leftOddsVal, placeHolder: "Enter text", keyboardType: .numberPad)
CustomTextfield(text: $rightOddsVal, placeHolder: "Enter text", keyboardType: .numberPad)
CustomTextfield(text: $state, placeHolder: "Enter text", keyboardType: .numberPad)
struct CustomTextfield: UIViewRepresentable {

    @Binding var text : String
    var placeHolder: String
    var keyboardType: UIKeyboardType

    final class Coordinator: NSObject {

        var textField: CustomTextfield

        init(_ textField: CustomTextfield) {
            self.textField = textField
        }

    }

    func makeCoordinator() -> DabbleTextfield.Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> UITextField {

        let textField = UITextField()
        textField.backgroundColor = .white
        textField.placeholder = self.placeHolder
        textField.keyboardType = self.keyboardType

        return textField
    }

    func updateUIView(_ uiView: UITextField, context: Context) {

    }

}
我想获取每个字段的值,并编写一些逻辑,计算出赢和输的金额,然后更新屏幕上的一些文本标签。我希望在所有字段都有值后自动更新赢/输标签,而不是让用户在看到他们可能赢或输的内容之前提交表单

以下是标签的外观:

问题:

CustomTextfield(text: $leftOddsVal, placeHolder: "Enter text", keyboardType: .numberPad)
CustomTextfield(text: $rightOddsVal, placeHolder: "Enter text", keyboardType: .numberPad)
CustomTextfield(text: $state, placeHolder: "Enter text", keyboardType: .numberPad)
struct CustomTextfield: UIViewRepresentable {

    @Binding var text : String
    var placeHolder: String
    var keyboardType: UIKeyboardType

    final class Coordinator: NSObject {

        var textField: CustomTextfield

        init(_ textField: CustomTextfield) {
            self.textField = textField
        }

    }

    func makeCoordinator() -> DabbleTextfield.Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> UITextField {

        let textField = UITextField()
        textField.backgroundColor = .white
        textField.placeholder = self.placeHolder
        textField.keyboardType = self.keyboardType

        return textField
    }

    func updateUIView(_ uiView: UITextField, context: Context) {

    }

}
  • textfielddidediting委托方法需要知道要触发的方法。这意味着,我需要修改CustomTextField以触发viewModel中将触发的方法。然后我可以触发赢/输计算方法。然而,我开始觉得这是一个如此简单的工作很多。看起来很乱

  • 我无法直接访问视图中的文本字段值。如果我使用SwiftUI的TextField组件,这将很简单。然而,正如您在上面的代码中所看到的,我正在使用UIKit的UIExtField组件包装在UIRepresentable结构中

  • 我所尝试的:

    CustomTextfield(text: $leftOddsVal, placeHolder: "Enter text", keyboardType: .numberPad)
    CustomTextfield(text: $rightOddsVal, placeHolder: "Enter text", keyboardType: .numberPad)
    CustomTextfield(text: $state, placeHolder: "Enter text", keyboardType: .numberPad)
    
    struct CustomTextfield: UIViewRepresentable {
    
        @Binding var text : String
        var placeHolder: String
        var keyboardType: UIKeyboardType
    
        final class Coordinator: NSObject {
    
            var textField: CustomTextfield
    
            init(_ textField: CustomTextfield) {
                self.textField = textField
            }
    
        }
    
        func makeCoordinator() -> DabbleTextfield.Coordinator {
            Coordinator(self)
        }
    
        func makeUIView(context: Context) -> UITextField {
    
            let textField = UITextField()
            textField.backgroundColor = .white
            textField.placeholder = self.placeHolder
            textField.keyboardType = self.keyboardType
    
            return textField
        }
    
        func updateUIView(_ uiView: UITextField, context: Context) {
    
        }
    
    }
    
    我有一个视图模型,我试图将其传递到CustomtextField

    我只是这样声明了我的环境变量:

       struct CustomTextfield: UIViewRepresentable {
    
          @EnvironmentObject var viewModel: EnvironmentObject<AnyObject>
          @Binding var text : String
          var placeHolder: String
          var keyboardType: UIKeyboardType
    
       CustomTextfield(viewModel: betViewModel as! EnvironmentObject<BetViewModel>, value: $oddsLeftValue, placeHolder: "Enter text", keyboardType: .numberPad)
    
    但我得到了以下错误:

    Type 'AnyObject' does not conform to protocol 'ObservableObject'
    
    我还尝试将绑定文本值设置为textField的值,但这也不起作用

    我希望有人能让我了解我做错了什么。我觉得我好像在兜圈子,这是因为试图重用UIRepresentable UIKit组件。这似乎限制了我,这导致了一些变通办法,对于我试图实现的目标来说,这些变通办法似乎是过火了

    我想做的就是允许用户输入他们的赔率和赌注,并让赢/输标签动态更新,而无需点击任何按钮。同时能够重用CustomTextField

    期待您的建议。
    提前感谢。

    以下内容使您的自定义文本字段可操作。。。对于更新外部绑定,希望这就是这么长描述的目标

    使用Xcode 11.4/iOS 13.4进行测试

    末尾的小
    TestCustomTextfield
    用于检查
    CustomTextfield
    中更改的更新标签

    struct CustomTextfield: UIViewRepresentable {
    
        @Binding var text : String
        var placeHolder: String
        var keyboardType: UIKeyboardType
    
        final class Coordinator: NSObject, UITextFieldDelegate {
    
            var parent: CustomTextfield
    
            init(_ parent: CustomTextfield) {
                self.parent = parent
            }
    
            func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
                parent.text = textField.text ?? ""
                return true
            }
        }
    
        func makeCoordinator() -> Coordinator {
            Coordinator(self)
        }
    
        func makeUIView(context: Context) -> UITextField {
    
            let textField = UITextField()
            textField.backgroundColor = .white
            textField.placeholder = self.placeHolder
            textField.keyboardType = self.keyboardType
            textField.setContentHuggingPriority(.required, for: .vertical)
            textField.delegate = context.coordinator
    
            return textField
        }
    
        func updateUIView(_ uiField: UITextField, context: Context) {
            if let text = textField.text as NSString? {
               parent.text = text.replacingCharacters(in: range, with: string)
            } else {
               parent.text = ""
            }
         }
    
    }
    
    struct TestCustomTextfield: View {
        @State private var value = ""
        var body: some View {
            VStack {
                Text("Label: \(value)")
                CustomTextfield(text: $value, placeHolder: "Your value", keyboardType: .numberPad)
            }
        }
    }
    

    以下选项使自定义文本字段可操作。。。对于更新外部绑定,希望这就是这么长描述的目标

    使用Xcode 11.4/iOS 13.4进行测试

    末尾的小
    TestCustomTextfield
    用于检查
    CustomTextfield
    中更改的更新标签

    struct CustomTextfield: UIViewRepresentable {
    
        @Binding var text : String
        var placeHolder: String
        var keyboardType: UIKeyboardType
    
        final class Coordinator: NSObject, UITextFieldDelegate {
    
            var parent: CustomTextfield
    
            init(_ parent: CustomTextfield) {
                self.parent = parent
            }
    
            func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
                parent.text = textField.text ?? ""
                return true
            }
        }
    
        func makeCoordinator() -> Coordinator {
            Coordinator(self)
        }
    
        func makeUIView(context: Context) -> UITextField {
    
            let textField = UITextField()
            textField.backgroundColor = .white
            textField.placeholder = self.placeHolder
            textField.keyboardType = self.keyboardType
            textField.setContentHuggingPriority(.required, for: .vertical)
            textField.delegate = context.coordinator
    
            return textField
        }
    
        func updateUIView(_ uiField: UITextField, context: Context) {
            if let text = textField.text as NSString? {
               parent.text = text.replacingCharacters(in: range, with: string)
            } else {
               parent.text = ""
            }
         }
    
    }
    
    struct TestCustomTextfield: View {
        @State private var value = ""
        var body: some View {
            VStack {
                Text("Label: \(value)")
                CustomTextfield(text: $value, placeHolder: "Your value", keyboardType: .numberPad)
            }
        }
    }
    

    您好,我已经添加了一行,以便在每次启动委托方法时打印字段的值,但由于某些原因,第一次启动时,该值为空,第二次启动时,它显示了应该在第一次启动时显示的值,依此类推。我在“return true”行之前加了一行。@LondonGuy,修正了这个问题。这让我找到了答案。updateUIView中的代码位于错误的位置。您好,我添加了一行,以便在每次启动委托方法时打印字段的值,但由于某些原因,第一次启动时,该值为空,第二次启动时,它显示了第一次启动时应显示的值,依此类推。我在“return true”行之前加了一行。@LondonGuy,修正了这个问题。这让我找到了答案。updateUIView中的代码位于错误的位置。