SwiftUI文本框+步进器

3

我正在尝试实现一个带有数字输入的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
      })
    }
  }
}
3个回答

4
这是因为在TextField中使用NumberFormatter会出现错误。您可能需要使用自定义绑定。
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()

0
在输入数字后,步进器失去了改变数字的能力。
我也遇到了这个问题,并发现onIncrementonDecrement操作仍然可以相应地触发。但是,我注意到与 TextField 的交互并没有释放用户对其焦点,这可通过不断闪烁的光标观察到。 当用户使用 Stepper 时将焦点从 TextField 中移除可以解决此问题。 在咨询 TextField 文档时,这也是有道理的:

如果值是字符串,则文本字段会在用户键入或以其他方式编辑字段中的文本时连续更新此值。对于非字符串类型,它会在用户提交其编辑(例如按下Return键)时更新该值。

(来源:https://developer.apple.com/documentation/swiftui/textfield
因此,我建议在用户与Stepper交互时模拟用户提交事件。这样可以避免不必要的类型转换,并使您继续利用TextField formatter初始化器。
原始代码的示例修改:
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


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接