用户输入的来自网格的文本字段数组

huangapple go评论53阅读模式
英文:

User inputted TextField Array from Grid

问题

I have a grid view that has two columns, one that is static that will be populated with names, and the second that is user-inputted numbers. I have two arrays, one full of the names, and one that is initialized to 0s for all numbers. I have it displayed as:

ScrollView{
    let lastRowIndex: Int = viewModel.names.count - 1
    LazyVGrid(columns: columns, alignment: .center, spacing: 0){
        Group {
            Text("Name")
            Text("Number")
        }.font(.headline)
        ForEach((0...lastRowIndex), id: \.self) { index in
            Text(viewModel.names[index])
            TextField("individual value", value: $viewModel.individualValues[index], format: .number)
        }
    }.padding(.horizontal)
}

This displays perfectly to start, two columns, one with every name in the array and one initialized to 0. But when I try to make any change to the number, as soon as I click off of the input it returns to 0. How do I set this up so that the numbers are saved in the individualValues array, displayed properly, and able to be used later?

Edit: My updated code is:

struct NamesAndTimes: Identifiable {
  let id = UUID()
  var userId: String
  var fullName: String
  var indivValue: Double
}

class AddTimesViewModel: ObservableObject {
     var namesAndTimes: [NamesAndTimes]

     ...
     init (users: [User]) {
        self.namesAndTimes = users.map{u in
          return NamesAndTimes(
            userId: u.id,
            fullName: u.firstName + " " + u.lastName,
            indivValue: 0
        )
        }
     }
}


struct AddTimes: View {
    @ObservedObject var viewModel: AddTimesViewModel 

    ...

    ScrollView{
        LazyVGrid(columns: columns, alignment: .leading, spacing: 0){
            Group {
                Text("Name")
                Text("Number")
            }.font(.headline)
            ForEach($viewModel.namesAndTimes) { $rT in
                Text(rT.fullName)
                TextField("type",
                          value: $rT.indivValue,
                          format: .number
                )
            }
        }.padding(.horizontal)
    }
}

Which works logically, but currently does not update the view. Even when I change the value, it displays as 0. If I click back, the typed-in value displays and is entered in Firebase if I click save, but I would like the view to display.

英文:

I have a grid view that has two columns, one that is static that will be populated with names, and the second that is user inputed numbers. I have two arrays, one full of the names, and one that is initialized to 0s for all numbers. I have it displayed as:

ScrollView{
            let lastRowIndex: Int = viewModel.names.count - 1
            LazyVGrid(columns: columns, alignment: .center, spacing: 0){
                Group {
                    Text("Name")
                    Text("Number")
                }.font(.headline)
                ForEach((0...lastRowIndex), id: \.self) { index in
                    Text(viewModel.names[index])
                    TextField("indiv value", value: $viewModel.individualValues[index], format: .number)
                }
            }.padding(.horizontal)
        }

This displays perfectly to start, two columns, one with every name in the array and one initialized to 0. But when I try to make any change to the number, as soon as I click off of the input it returns to 0. How do I set this up so that the numbers are saved in the individualValues array, displayed properly, and able to be used later?

Edit: My updated code is:

struct NamesAndTimes: Identifiable {
  let id = UUID()
  var userId: String
  var fullName: String
  var indivValue: Double
}

class AddTimesViewModel: ObservableObject {
     var namesAndTimes: [NamesAndTimes]

     ...
     init (users: [User]) {
        self.namesAndTimes = users.map{u in
          return NamesAndTimes(
            userId: u.id,
            fullName: u.firstName+" "+u.lastName,
            indivValue: 0
        )
        }
     }
}


struct AddTimes: View {
    @ObservedObject var viewModel: AddTimesViewModel 

    ...

    ScrollView{
            LazyVGrid(columns: columns, alignment: .leading, spacing: 0){
                Group {
                    Text("Name")
                    Text("Number")
                }.font(.headline)
                ForEach($viewModel.namesAndTimes) { $rT in
                    Text(rT.fullName)
                    TextField("type",
                              value: $rT.indivValue,
                              format: .number
                    )
                }
            }.padding(.horizontal)
        }

Which works logically, but currently does not update the view. Even when I change the value, it displays as 0. If I click back the typed in value displays, and is entered in Firebase if I click save, but I would like the view to display.

答案1

得分: 1

尽管您的代码可能能够工作,前提是您使用类似于:@StateObject var viewModel = TheModel()

但是,最好为您的namesindividualValues使用更强大的结构,而不是单独的数组,并通过一个共同的index来访问它们,这不是一个好主意,也不推荐使用。

以下是我的示例代码,可以为您实现您所要求的功能:“如何设置这样的结构,使数字保存在individualValues数组中,正确显示,并能够以后使用”:

// -- 在这里,名称和值被绑定在一起
struct ModelItem: Identifiable {
    let id = UUID()
    var name: String
    var value: Int
}

class TheModel: ObservableObject {
    @Published var items: [ModelItem] = [ModelItem(name: "item-1", value: 1),
                                         ModelItem(name: "item-2", value: 2),
                                         ModelItem(name: "item-3", value: 3)]
}

struct ContentView: View {
    @StateObject var viewModel = TheModel() // <-- 在这里

    var columns: [GridItem] = [GridItem(.flexible()), GridItem(.flexible())]

    var body: some View {
        ScrollView{
            LazyVGrid(columns: columns, alignment: .center, spacing: 0){
                Group {
                    Text("名称")
                    Text("数字")
                }.font(.headline)
                ForEach($viewModel.items) { $item in   // <-- 使用 $,而不是索引
                    Text(item.name)
                    TextField("个体值", value: $item.value, format: .number)  // <-- 在这里
                }
            }.padding(.horizontal)
        }
    }
}

请注意,我已经将示例代码中的HTML实体(例如&quot;)替换为正常的文本,以便代码能够正确运行。

英文:

Although your code could work, given you use something like: @StateObject var viewModel = TheModel().

You would be better off using a more robust structure for your names and individualValues, than
the separate arrays, and accessing them through a common index, not a good idea and not recommended.

Here is my example code of that approach that works for me and achieve what you ask:
How do I set this up so that the numbers are saved in the individualValues array, displayed properly, and able to be used later

// -- here, name and value are tied together
struct ModelItem: Identifiable {
    let id = UUID()
    var name: String
    var value: Int
}

class TheModel: ObservableObject {
    @Published var items: [ModelItem] = [ModelItem(name: &quot;item-1&quot;, value: 1),
                                         ModelItem(name: &quot;item-2&quot;, value: 2),
                                         ModelItem(name: &quot;item-3&quot;, value: 3)]
}

struct ContentView: View {
    @StateObject var viewModel = TheModel() // &lt;-- here
    
    var columns: [GridItem] = [GridItem(.flexible()), GridItem(.flexible())]
    
    var body: some View {
        ScrollView{
            LazyVGrid(columns: columns, alignment: .center, spacing: 0){
                Group {
                    Text(&quot;Name&quot;)
                    Text(&quot;Number&quot;)
                }.font(.headline)
                ForEach($viewModel.items) { $item in   // &lt;-- use $, and not index
                    Text(item.name)
                    TextField(&quot;indiv value&quot;, value: $item.value, format: .number)  // &lt;-- here
                }
            }.padding(.horizontal)
        }
    }
}

huangapple
  • 本文由 发表于 2023年6月13日 04:55:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76460274.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定