【问题标题】:SwiftUI TextField Number InputSwiftUI TextField 数字输入
【发布时间】:2021-09-01 19:23:54
【问题描述】:

我正在尝试让用户输入两个数字,然后显示这些数字并将它们相加。目前,为了更新状态变量,您需要按回车键。有没有办法像文本一样更新状态?我也将代码作为字符串输入,但无法将其转换为 int,因此可以正确地将数字相加。如果有人知道如何正确转换,我将不胜感激。

struct ContentView: View {
    @State private var numOne: Int = 0
    @State private var numTwo: Int = 0

    var body: some View {
        NavigationView {
            VStack {
                Form {
                    Section {
                        TextField("Number One", value: $numOne, formatter: NumberFormatter())
                            .keyboardType(.numberPad)

                        TextField("Number Two", value: $numTwo, formatter: NumberFormatter())
                            .keyboardType(.numberPad)
                    }

                    NavigationLink(
                        destination: addedView(numOne: $numOne, numTwo: $numTwo),
                        label: {
                            Text("Navigate")
                        }
                    )
                }
            }
        }
    }
}

struct addedView: View {
    @Binding var numOne: Int
    @Binding var numTwo: Int
    @State private var added: Int = 0

    var body: some View {
        VStack {
            Text("\(numOne)")
            Text("\(numTwo)")
        }
    }
}

【问题讨论】:

  • 您希望在数字实时更新时显示这些数字吗?或者与您如何在NavigationLink 的目的地显示它们有关?
  • @George 我试图让文本字段接受作为 int 输入的数字或将输入的字符串转换为 int。我正在尝试将用户输入的两个数字相加,但是当我将其作为字符串执行时,它只是将数字放在一起而不是相加。

标签: swift swiftui textfield


【解决方案1】:

这显示了如何强制 TextFields 为整数,以及如何将它们加在一起以获得结果。

主要区别在于格式化程序的numberStyle.decimal。这意味着你只会得到整数/整数。

Ints 时添加结果,因此添加了数字。如果您在它们都是Strings 时添加,它们将连接在一起。例如。你希望5 + 1015,而不是510

然后,您可以将 result 传递给子视图或 NavigationLink(如果您愿意)。

struct ContentView: View {
    @State private var numOne: Int = 0
    @State private var numTwo: Int = 0

    private static let formatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        return formatter
    }()

    private var result: Int {
        numOne + numTwo
    }

    var body: some View {
        NavigationView {
            VStack {
                Form {
                    Section {
                        TextField("Number One", value: $numOne, formatter: Self.formatter)
                            .keyboardType(.numberPad)

                        TextField("Number Two", value: $numTwo, formatter: Self.formatter)
                            .keyboardType(.numberPad)
                    }

                    Section {
                        Text("Result: \(result)")
                    }
                }
            }
        }
    }
}

请注意,NumberFormatter 是静态创建的,并且仅创建一次。这是因为创建它们非常昂贵,尤其是 每个 渲染两次。

【讨论】:

    【解决方案2】:

    这使用 Combine 来确保输入的文本是数字,然后将其更改为 Int 以用于计算。返回值是一个闭包,您可以使用它来

    struct EditableInt : View {
    
        var intString: String = ""
        var onChanged: (Int) -> Void
    
        init(_ int: Int?, onChanged: @escaping (Int) -> Void) {
            if let int = int,
               let formattedInt = Formatter.numberFormatter.string(from: int as NSNumber){
                self.intString = formattedInt
            } else {
                intString = ""
            }
            self.onChanged = onChanged
        }
        
        @State private var editableInt: String = ""
    
        var body: some View {
                TextField(" " + intString + " ", text: $editableInt)
                .onReceive(Just(editableInt)) { newValue in
                    let editableInt = newValue.filter { "0123456789".contains($0) }
                    if editableInt != intString {
                        if let returnInt = Int(editableInt) {
                            onChanged(returnInt)
                        }
                    }
                }
            .onAppear { self.editableInt = self.intString }
        }
    }
    

    上面是可重用的,并且从另一个视图中调用,如下所示:

    struct OtherView: View {
    
        @State var otherViewInt = 0
    
            var body: some View {
                EditableInt(otherViewInt) { newInt in
                    otherViewInt = newInt
                }
            }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 1970-01-01
      相关资源
      最近更新 更多