ios 缺少参数,但需要根据用户输入更改参数

brtdzjyr  于 2022-11-19  发布在  iOS
关注(0)|答案(2)|浏览(120)

此文件用于应用程序的主结构。这就是错误的来源,错误是“调用中缺少参数'numberOfDoors'的参数”。这是因为它希望我添加

ContentView(numberOfDoors: <#Int#>)

但我很难找到如何获得用户选择的int值,而不是静态地输入一个数字。

import SwiftUI

@main
struct NumOfDoorsApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
 }

这是我的项目文件。

import SwiftUI

struct ContentView: View {

@State var numberOfDoors: Int
@State var multiOptions: Array<String>

init(numberOfDoors: Int) {
    self.numberOfDoors = numberOfDoors
    self.multiOptions = [String](repeating: "", count: numberOfDoors)
}

var body: some View {
    NavigationView {
        Form{
            Section {
                Picker("Number of doors", selection: $numberOfDoors) {
                    ForEach(1 ..< 64) {
                        Text("\($0) doors")
                    }
                }
                
                ForEach(multiOptions.indices, id: \.self) { index in
                    TextField("Enter your option...", text: $multiOptions[index])
                        .padding()
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                }
            }
            
            Section {
                Text("\(numberOfDoors + 1)")
            }
        }
    }
}
}
toiithl6

toiithl61#

SwiftUI编程最重要的部分之一是为视图创建适当的模型。
@State属性对于本地的、通常是独立的属性来说是可以的,但是对于主数据模型或者需要由用户操作的模型来说,它们通常不是一个好的解决方案。
在您的示例中,您希望阵列的大小根据选定的门数进行更改,因此您需要为该过程代码提供位置;模型就是那个地方。
下面是一个可以使用的简单模型对象

class DoorModel: ObservableObject {
    
    @Published var numberOfDoors: Int {
        didSet {
            self.adjustArray(newSize: numberOfDoors)
        }
    }
    @Published var doors:[String]
    
    init(numberOfDoors: Int) {
        self.numberOfDoors = numberOfDoors
        self.doors = [String](repeating: "", count: numberOfDoors)
    }
    
    private func adjustArray(newSize: Int) {
        let delta = newSize - doors.count
        
        print("new size = \(newSize) Delta = \(delta)")
        
        if delta > 0 {
            doors.append(contentsOf:[String](repeating: "", count: delta))
        } else if delta < 0 {
            doors.removeLast(-delta)
        }
    }
}

注意你仍然需要通过初始化程序为你的模型提供一个起始的门数。每当这个值改变时,didSet属性observer调用一个函数来添加或删除数组末尾的元素。
您可以在视图中使用这个模型和@StateObject装饰器。

struct ContentView: View {
    
    @StateObject var model = DoorModel(numberOfDoors: 1)
    
    var body: some View {
        NavigationView {
            Form{
                Section {
                    Picker("Number of doors", selection: $model.numberOfDoors) {
                        ForEach(1 ..< 64) { index in
                            Text("\(index) doors").tag(index)
                        }
                    }
                    
                    ForEach($model.doors.indices, id: \.self) { index in
                        TextField("Enter your option...", text: $model.doors[index])
                            .padding()
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                    }
                }
            }
        }
    }
}

我添加了.tag修饰符,以确保选取器能够正确处理从1开始的列表;默认情况下,标记将从0开始。

tvmytwxo

tvmytwxo2#

在我看来,你的代码有两个问题。
1.不要用参数初始化ContentView。特别是,因为你想从0个门开始,让用户选择多少个门。
1.您无法直接初始化@State值,如下所示:self.门数=门数。
我建议使用下面的代码,它对我很有效。

import SwiftUI

struct ContentView: View {
    
    @State private var numberOfDoors: Int
    @State private var multiOptions: Array<String>

    init() {
        _numberOfDoors = State(wrappedValue: 0)
        _multiOptions = State(wrappedValue: [String](repeating: "", count: 1))
    }

    var body: some View {
        NavigationView {
            Form{
                Section {
                    Picker("Number of doors", selection: $numberOfDoors) {
                        ForEach(1 ..< 64) {
                            Text("\($0) doors")
                        }
                    }
                    
                    ForEach(multiOptions.indices, id: \.self) { index in
                        TextField("Enter your option...", text: $multiOptions[index])
                            .padding()
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                    }
                }
                
                Section {
                    Text("\(numberOfDoors + 1)")
                }
            }
        }
    }
}

问题是,当您初始化ContentView时,@State或@StateObject变量还不存在。您首先需要初始化视图,然后才能分配@State变量。
@State变数会 Package 在属性 Package 函数中,其中初始化时的原始变数是_variable。因此,您需要以下列方式初始化@State变数:

_myVariable = State(wrappedValue: myContent)

如果你不这样做,你会得到你提到的错误。

相关问题