SwiftUI文本字段+步进器

6bc51xsx  于 2023-01-25  发布在  Swift
关注(0)|答案(3)|浏览(203)

我正在尝试实现一个带有数字输入的TextField和Stepper来控制数量。在TextField中输入一个数字后,Stepper失去了更改数字的能力。我很确定绑定值有一个技巧,但不能弄清楚到底是什么。

struct TestView: View {
  @State var quantity: Int = 0

  var body: some View {
    HStack {
      TextField("", value: $quantity, formatter: NumberFormatter())
      Stepper("", onIncrement: {
        self.quantity += 1
      }, onDecrement: {
        self.quantity -= 1
      })
    }
  }
}
nwlls2ji

nwlls2ji1#

这是因为在TextField中使用NumberFormatterbugged
您可能需要改用自定义绑定:

struct ContentView: View {
    @State var quantity: Int = 0

    static let formatter = NumberFormatter()

    var binding: Binding<String> {
        .init(get: {
            "\(self.quantity)"
        }, set: {
            self.quantity = Int($0) ?? self.quantity
        })
    }

    var body: some View {
        HStack {
            TextField("", text: binding)
            Stepper("", onIncrement: {
                self.quantity += 1
            }, onDecrement: {
                self.quantity -= 1
            })
        }
    }
}

也不要每次都重新创建NumberFormatter

TextField("", value: $quantity, formatter: NumberFormatter())

可以使用仅创建一次的静态属性:

static let formatter = NumberFormatter()
ffvjumwh

ffvjumwh2#

我在StepperTextField上也遇到过类似的问题,所以我决定制作一个Swift包来解决这个问题。
https://github.com/joe-scotto/TextFieldStepper

watbbzwu

watbbzwu3#

在文本字段中输入数字后,步进器将无法更改数字。
我也遇到过这个问题,实际上发现onIncrementonDecrement操作会继续相应地触发。但是,我注意到,与Stepper交互并不会释放用户对TextField的关注,正如通过持续 Flink 的光标所观察到的那样。

    • 在用户使用Stepper时,从TextField中删除焦点可解决此问题。**

在查阅TextField文档时,这也是有意义的:
如果值为字符串,则文本字段会在用户键入或编辑字段中的文本时不断更新此值。对于非字符串类型,它会在用户提交编辑内容(如按Return键)时更新值。
(来源:https://developer.apple.com/documentation/swiftui/textfield
因此,我建议在用户使用Stepper时模拟用户提交事件,这样可以避免不必要的类型转换,并允许您继续利用TextFieldformatter初始化器。
原始代码的修改示例:

struct TestView: View {
  @State var quantity: Int = 0

  // Keep track of which field the user is focused on
  @FocusState private var focusedField: String?

  var body: some View {
    HStack {
      TextField("", value: $quantity, formatter: NumberFormatter())
        .focused($focusedField, equals: "quantity")
      Stepper("", onIncrement: {
        // Remove the focus from the (text) field
        focusedField = nil

        self.quantity += 1
      }, onDecrement: {
        // Remove the focus from the (text) field
        focusedField = nil

        self.quantity -= 1
      })
    }
  }
}

有关详细信息,另请参阅focused(_:equals:)@FocusState文档:https://developer.apple.com/documentation/swiftui/view/focused(_:equals:)https://developer.apple.com/documentation/SwiftUI/FocusState

相关问题