提问者:小点点

带有@Binding var的SwiftUI类的初始化


我有一个类,我想用在另一个视图中设置的绑定变量初始化它。

查看-

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())

                }
            }
        }
    }

需要使用 @Binding var $numberofNumbers 初始化的类 -

import SwiftUI

class MultiplicationPractice:ObservableObject {

    @Binding var numberOfNumbers:Int
    var classNumofNumbers:Int

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

init语句显然给出了一个错误,即self未初始化,而实例var用于初始化,这是不允许的。

我该如何避免这种情况?需要使用用户在第一个视图中输入的编号初始化该类。我在这里写了大概的代码,所以请忽略任何打字错误。


共2个答案

匿名用户

通常,您会在CoverPageView中使用起始值初始化乘法练习:

@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
...

在您的特定情况下,我甚至会在您的<code>CoverPageView</code>中删除<code>numberOfNumbers</code>变量,而是使用上述<code>someVar</code>的直接变量:

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

您会注意到我作为绑定传入了@Object的sub-var。我们可以使用观测对象来做到这一点。

我现在明白了您要做的事情,您希望在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)
    }
}

匿名用户

好吧,我真的不明白你的问题,所以我只列出几个例子,希望其中一个就是你正在寻找的。

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)")
    }
}