使用 @Binding var 为 SwiftUI class 初始化

Init for a SwiftUI class with a @Binding var

我有一个 class,我想用另一个视图中设置的绑定变量对其进行初始化。

查看 ->

struct CoverPageView: View {
    @State  var numberOfNumbers:Int

    var body: some View {
        NavigationView {
            GeometryReader { geometry in
                VStack(alignment: .center, spacing: 0){
                    TextField("Multiplication Upto:", value: self.$numberOfNumbers, formatter: NumberFormatter())

                }
            }
        }
    }

CLASS 需要使用 @Binding var $numberofNumbers -

进行初始化
import SwiftUI

class MultiplicationPractice:ObservableObject {

    @Binding var numberOfNumbers:Int
    var classNumofNumbers:Int

    init() {
        self.classNumofNumbers = self.$numberOfNumbers
    }
}

init语句明显报错self未初始化,正在使用实例var初始化,这是不允许的

我该如何避免这种情况? class 需要用用户在第一个视图中输入的数字进行初始化。我写了大约。代码在这里所以请忽略任何拼写错误。

好吧,我不太明白你的问题,所以我只是想举几个例子,希望其中之一就是你要找的。


struct SuperView: some View {
    @State var value: Int = 0

    var body: some View {
        SubView(value: self.$value)
    }
}
struct SubView: View {
    @Binding var value: Int

    // This is the same as the compiler-generated memberwise initializer
    init(value: Binding<Int>) {
        self._value = value
    }

    var body: some View {
        Text("\(value)")
    }
}

如果我误解了你只是想获取当前值,请执行此操作

struct SuperView: some View {
    @State var value: Int = 0

    var body: some View {
        SubView(value: self.value)
    }
}
struct SubView: View {
    let value: Int

    // This is the same as the compiler-generated memberwise initializer
    init(value: Int) {
        self.value = value
    }

    var body: some View {
        Text("\(value)")
    }
}

通常您会在 CoverPageView 中使用起始值初始化 MultiplicationPractice:

@ObservedObject var someVar = MultiplicationPractice(NoN:123)

当然,添加支持的 init 语句:

class MultiplicationPractice:ObservableObject {
    init(NoN: Int) {
        self.numberOfNumbers = val
    }

你不想用@Binding 包装你的 var,而是用@Published 包装它:

class MultiplicationPractice:ObservableObject {

@Published var numberOfNumbers:Int
...

在您的特定情况下,我什至会在您的 CoverPageView 中删除 numberOfNumbers 变量,而是使用上述 someVar:

的直接变量
struct CoverPageView: View {
    //removed @State  var numberOfNumbers:Int
    @ObservedObject var someVar = MultiplicationPractice(123)
    
    ...
    
    TextField("Multiplication Upto:", value: self.$someVar.numberOfNumbers, formatter: NumberFormatter())

您会注意到我将@ObservedObject 的子变量作为绑定传入。我们可以使用 ObservableObjects 来做到这一点。


编辑

我现在明白你想做什么了,你想在你的 ViewModel 中传递一个绑定,并在你的视图和模型之间建立一个间接的连接。虽然这可能不是我个人的做法,但我仍然可以提供一个工作示例。

这是一个使用您的结构名称的简单示例:

struct MultiplicationGame {
    @Binding var maxNumber:String
    init(maxNumber: Binding<String>) {
        self._maxNumber = maxNumber
        print(self.maxNumber)
    }
}

class MultiplicationPractice:ObservableObject {
    var numberOfNumbers: Binding<String>
    @Published var MulGame:MultiplicationGame
    
    init(numberOfNumbers: Binding<String> ) {
        self.numberOfNumbers = numberOfNumbers
        self.MulGame = MultiplicationGame(maxNumber: numberOfNumbers)
    }
    
}
struct ContentView: View {
    @State var someText: String
    @ObservedObject var mulPractice: MultiplicationPractice
    init() {
        let state = State(initialValue: "")
        self._someText = state
        self.mulPractice = MultiplicationPractice(numberOfNumbers: state.projectedValue)
    }
    var body: some View {
        TextField("put your text here", text: $someText)
    }
}