难以将用户输入从TextField作为Double/Date进行传递



我正在学习如何使用Apple提供的教程进行编码。我正处于学习使用绑定传递数据的阶段。

我还在学习,所以请期待下面的两个问题,我试图找到答案,但找不到任何有说服力的东西,所以发了这篇文章。提前感谢您的耐心:(

  1. 总结问题教程中提供的示例使用TextField来允许用户输入。例如,我正试图这样做,以便人们可以输入一年(2008年(,但这不起作用,因为我试图传递给的数据是Double,所以我收到了一条错误消息。我也尝试过使用日期选择器,但这让我不得不处理日期,这在现阶段对我来说似乎非常复杂。

  2. 描述你所尝试的我已经尝试过将来自TextField的用户输入视为Double,但每次尝试都会导致更多的错误消息。到目前为止,一切都不起作用。

  3. 适当时,显示一些代码:

我的数据模型:

struct Animal: Identifiable {
let id: UUID
var name: String
var birthyear: Int
}

init(id: UUID = UUID(), name: String, birthyear: Int){
self.id = id
self.name = name
self.birthyear = birthyear
}
extension Animal {
static var data: [Animal] {
[
Animal(name: "Félix", birthyear: 1999
]
}
}
extension Animal {
struct Data {
var name: String = ""
var birthyear: Double = 1999       
}

var data: Data {
return Data (name: name, birthyear: Double(birthyear))
}

mutating func update(from data: Data) {
name = data.name
birthyear = Int(data.birthyear)
}
}

以及我的TextField出现的代码(EditView(:

import SwiftUI
struct EditView: View {
@Binding var animData: Animal.Data
var body: some View {
Form {
Section(header: Text("Animal Info")){
List {
TextField("Title", text: $animData.name)
HStack {
TextField("Birth Year", text: $animData.vaccinyear)
}
}
}
}
}
struct EditView_Previews: PreviewProvider {
static var previews: some View {
EditView(animData: .constant(Animal.data[0].data))
}
}

现在我有两个问题:

如果我希望数据以Double形式传递,那么我上面的代码实际上可以工作,我该怎么办?它使用滑块,但这是一种荒谬的方式。

(工作的滑块代码(

var body: some View {
Form {
Section(header: Text("Animal Info")){
List {
TextField("Title", text: $animData.name)
HStack {
Slider(value: $animData.birthyear, in: 1999...2021, step: 1.0) {
Text("Length")
}
}
}
}

编辑:这里的解决方案:SwiftUI-如何创建只接受数字的TextField

TextField("Birth Year", text: $animData.birthyear)
.keyboardType(.numberPad)
.onReceive(Just(animData.birthyear)) { newValue in
let filtered = newValue.filter { "0123456789".contains($0) }
if filtered != newValue {
self.animData.birthyear = filtered
}
}

如果您对仍然可以保留Int的解决方案感兴趣,则此修改通过使用具有String值的中间@State变量来进行,然后在有效的情况下分配实际的Int值。

struct ContentView : View {
@State var birthyear = 1999
@State var stringBirthyear = ""

var birthyearBinding : Binding<String> {
.init {
print("returning",birthyear)
return "(birthyear)"
} set: { (newValue) in
if let intVal = Int(newValue) {
DispatchQueue.main.async {
print("Setting birthyear to",intVal)
self.birthyear = intVal
}
}
}
}

var body: some View {
Text("(birthyear)")
TextField("Birth Year", text: $stringBirthyear)
.keyboardType(.numberPad)
.onReceive(Just(stringBirthyear)) { newValue in
let filtered = newValue.filter { "0123456789".contains($0) }
if filtered != newValue {
print(filtered,newValue)
stringBirthyear = filtered
}
if let intVal = Int(filtered) {
birthyear = intVal
}
}
.onAppear {
stringBirthyear = "(birthyear)"
}
}
}

最新更新