SwiftUI和Combine-如何创建具有与用户选择对应的字段数的表单
我正在创建一个基本的租金分摊应用程序,以了解Swift UI和Combine。我希望有一个主屏幕,用户首先选择与他们共享的室友数量,然后根据该选择,向他们显示一个表单,其中包含与该数字对应的字段。到目前为止,我有HomeView:SwiftUI和Combine-如何创建具有与用户选择对应的字段数的表单,swift,swiftui,Swift,Swiftui,我正在创建一个基本的租金分摊应用程序,以了解Swift UI和Combine。我希望有一个主屏幕,用户首先选择与他们共享的室友数量,然后根据该选择,向他们显示一个表单,其中包含与该数字对应的字段。到目前为止,我有HomeView: import SwiftUI import Combine struct HomeScreenView: View { @ObservedObject private var viewModel: HomeScreenViewModel
import SwiftUI
import Combine
struct HomeScreenView: View {
@ObservedObject private var viewModel: HomeScreenViewModel
init(viewModel: HomeScreenViewModel){
self.viewModel = viewModel
}
var body: some View {
NavigationView {
VStack {
Text("Welcome to Fair Rent!")
Text("Please select how many housemates you live with:")
.lineLimit(nil)
.padding(5.0)
NavigationLink(destination: FairRentView(viewModel: FairRentViewModel(Amounts())))
{
Text("1")
}
NavigationLink(destination: FairRentView(viewModel: FairRentViewModel(Amounts())))
{
Text("2")
}
NavigationLink(destination: FairRentView(viewModel: FairRentViewModel(Amounts())))
{
Text("3")
}
NavigationLink(destination: FairRentView(viewModel: FairRentViewModel(Amounts())))
{
Text("4")
}
NavigationLink(destination: FairRentView(viewModel: FairRentViewModel(Amounts())))
{
Text("5")
}
NavigationLink(destination: FairRentView(viewModel: FairRentViewModel(Amounts())))
{
Text("6")
}
NavigationLink(destination: FairRentView(viewModel: FairRentViewModel(Amounts())))
{
Text("7")
}
}
}
}
}
struct HomeScreenView_Previews: PreviewProvider {
static var previews: some View {
HomeScreenView(viewModel: HomeScreenViewModel(Variables()))
}
}
根据他们点击的数字,他们将被带到FairRentView:
import SwiftUI
import Combine
struct FairRentView: View {
@ObservedObject private var viewModel: FairRentViewModel
init(viewModel: FairRentViewModel){
self.viewModel = viewModel
}
var body: some View {
NavigationView {
Form {
Section(header: Text("Enter the total monthly rent:")) {
TextField("Total rent", text: $viewModel.amount.totalRent)
.keyboardType(.decimalPad)
}
Section(header: Text("Enter your monthly income:")) {
TextField("Your monthly wage", text: $viewModel.amount.myMonthlyIncome)
.keyboardType(.decimalPad)
}
Section(header: Text("Enter your housemate's monthly income:")) {
TextField("Housemate's monthly income", text: $viewModel.amount.housemateMonthlyIncome)
.keyboardType(.decimalPad)
}
Section {
Text("Your share: £\(viewModel.yourShare, specifier: "%.2f")")
}
}
.navigationBarTitle("FairRent")
}
}
}
struct FairRentView_Previews: PreviewProvider {
static var previews: some View {
FairRentView(viewModel: FairRentViewModel(Amounts()))
}
}
我希望租金以工资为基础。正如您所看到的,目前只有一个表单字段可以输入室友的工资,不考虑是否有几个室友。我希望这些字段的编号与用户在主屏幕上选择的编号相对应。我对SwiftUI非常陌生,不知道最好的方法是什么。谁能给我指一下正确的方向吗?我正在尽力使用Combine并确认MVVM模式
谢谢因为SwiftUI是数据驱动的,视图是基于数据生成的,所以您需要一个位置来存储每个室友的数量,比如在视图模型中的数组中。然后在数组上循环生成
TextField
s
以下是一个概念性示例:
class FairRentViewModel: ObservableObject {
@Published var incomes: [String]
init(for housemates: Int) {
self.incomes = Array(repeating: "", count: housemates)
}
}
(我使用了字符串
作为简化,因此以后更容易绑定到文本字段
)
然后视图将在阵列上循环:
struct FairRentView: View {
@ObservedObject var vm: FairRentViewModel
var body: some View {
ForEach(vm.incomes.indices, id: \.self) { idx in
TextField("Housemate \(idx + 1)", text: self.$vm.incomes[idx])
}
}
}
然后在父视图中,您可以使用正确的家庭数量实例化FairRentView
。同样,这是一种简化,因为您可能也希望在这里有一个循环
struct HomeScreenView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: FairRentView(vm: FairRentViewModel(for: 2)) {
Text(2)
}
NavigationLink(destination: FairRentView(vm: FairRentViewModel(for: 3)) {
Text(3)
}
// .. etc
}
}
}
}
感谢@NewDev提供您的解决方案。您的
FairRentViewModel中的室友
来自哪里?这就是FairRentViewModel
如何由HomeScreenView
实例化的:例如FairRentViewModel(for:2)
并传递到FairRentView
视图谢谢@NewDev-我收到了“从初始值设定项返回,但不初始化所有存储的属性”此错误,因此您是否想知道您是在我的简化示例中看到它,还是将其集成到代码中?我正在使用您的示例并尝试集成到我的代码中