我目前正在建立一个页面,以将玩家信息添加到本地数据库。对于每个与播放器结构中的元素链接的输入,我都有一个TextFields集合。
APP_URL=http://localhost
我的播放器结构是
var body: some View {
VStack {
TextField("First Name", text: $player.FirstName)
.textFieldStyle(RoundedBorderTextFieldStyle())
TextField("Last Name", text: $player.LastName)
.textFieldStyle(RoundedBorderTextFieldStyle())
TextField("Email", text: $player.eMail)
.textFieldStyle(RoundedBorderTextFieldStyle())
TextField("Shirt Number", text: $player.ShirtNumber)
.textFieldStyle(RoundedBorderTextFieldStyle())
TextField("NickName", text: $player.NickName)
.textFieldStyle(RoundedBorderTextFieldStyle())
TextField("Height", text: $player.Height)
.textFieldStyle(RoundedBorderTextFieldStyle())
TextField("Weight", text: $player.Weight)
.textFieldStyle(RoundedBorderTextFieldStyle())
Button(action: {
submitPlayer(player: self.player)T
}) {
Text("Submit")
}
Spacer()
}
}
问题在于ShirtNumber,Height和Weight均为Int值。将它们绑定到TextField时,出现错误消息struct Player: Hashable, Codable, Identifiable {
var id: Int
var FirstName: String
var LastName: String
var NickName: String
var eMail: String
var ShirtNumber: Int
var Height: Int
var Weight: Int
}
。我研究过的关于SwiftUI的一切都说不可能有绑定了Int值的TextField。
我的问题是,是否可以创建一个扩展TextField但仅允许Int输入并绑定一个Int变量的新类?
Cannot convert value of type 'Binding<Int>' to expected argument type 'Binding<String>'
到目前为止,我所能找到的只是对this问题中部分问题的答案(仅接受Int输入)。我正在寻找一种将其与struct IntTextField: TextField {
init(_ text: String, binding: Binding<Int>) {
}
}
结合使用的方法。
感谢您的帮助。
答案 0 :(得分:5)
只是为了让它更容易观察。
改变这个:
TextField("", text: $intvalue)
那个
TextField("Value", value: $amount, formatter: NumberFormatter())
答案 1 :(得分:2)
实际上,您可以将许多类型与TextField
绑定:
@State var weight: Int = 0
var body: some View {
Group{
Text("\(weight)")
TextField("Weight", value: $weight, formatter: NumberFormatter())
}}
答案 2 :(得分:0)
当然可以使用
TextField("", value: $value, formatter: NumberFormatter())
// .keyboardType(UIKeyboardType.decimalPad) // << uncomment for num pad
甚至使用数字键盘,但这不会阻止在这样的TextField
中输入非数字字符,并且直到调用commit formatter
来验证输入为止。也许Apple会在将来为我们提供即时验证输入的可能性,但不是现在,...所以我更喜欢采用其他方式
在这里,我的方法是为数字值(Int,Float,Double等)提供文本字段,该字段用于验证输入和特定类型的限制(例如,不允许输入更长的值然后适合Int最大允许值)。希望这也会对某人有所帮助。 (当然,根据使用需要可以配置字体,大小,颜色等配置)
struct NumberTextField<V>: UIViewRepresentable where V: Numeric & LosslessStringConvertible {
@Binding var value: V
typealias UIViewType = UITextField
func makeUIView(context: UIViewRepresentableContext<NumberTextField>) -> UITextField {
let editField = UITextField()
editField.delegate = context.coordinator
return editField
}
func updateUIView(_ editField: UITextField, context: UIViewRepresentableContext<NumberTextField>) {
editField.text = String(value)
}
func makeCoordinator() -> NumberTextField.Coordinator {
Coordinator(value: $value)
}
class Coordinator: NSObject, UITextFieldDelegate {
var value: Binding<V>
init(value: Binding<V>) {
self.value = value
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
let text = textField.text as NSString?
let newValue = text?.replacingCharacters(in: range, with: string)
if let number = V(newValue ?? "0") {
self.value.wrappedValue = number
return true
} else {
if nil == newValue || newValue!.isEmpty {
self.value.wrappedValue = 0
}
return false
}
}
func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
if reason == .committed {
textField.resignFirstResponder()
}
}
}
}
struct TestTextFieldWithNumbers: View {
@State private var value = 0
var body: some View {
VStack {
Text("Current value: \(value)")
Divider()
TextField("", value: $value, formatter: NumberFormatter())
// .keyboardType(UIKeyboardType.decimalPad)
Divider()
NumberTextField(value: $value)
.frame(height: 32)
}
}
}
struct TestTextFieldWithNumbers_Previews: PreviewProvider {
static var previews: some View {
TestTextFieldWithNumbers()
}
}
答案 3 :(得分:0)
试图让它在没有 UIKit 的情况下工作,因为我正在尝试构建一个小的 macOS 应用程序,所以 UIKit 不存在,所以找到了一个使用两个变量的解决方案(不是最干净但有效)
变量声明:
@State var minutes = 0
@State var minutesString = "0"
TextField 和步进器:
HStack {
TextField("minutes", text: self.$minutesString)
.onReceive(Just(self.minutesString)) { newValue in
let filtered = newValue.filter { $0.isNumber }
if filtered != newValue {
self.minutesString = filtered
self.minutes = Int(filtered) ?? -1
}
}
Stepper("minutes", value: $minutes).onChange(of: self.hours) { newValue in
self.minutesString = String(newValue)
}
.labelsHidden()
}
这将导致在写入 textField 或步进器时更改两个变量,并且不允许输入数字以外的任何内容。
我对整个 swift 事情有点陌生,因此非常感谢任何反馈。