【问题标题】:Init for a SwiftUI class with a @Binding var使用 @Binding var 初始化 SwiftUI 类
【发布时间】:2020-11-10 08:47:43
【问题描述】:

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

查看->

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 进行初始化,这是不允许的。

我该如何规避这个问题?该类需要使用用户在第一个视图中输入的数字进行初始化。我写了大约。代码在这里,请忽略任何错别字。

【问题讨论】:

  • 你不要用var classNumofNumbers:Int传递,直接从init函数传递。 MultiplicationPractice(numberOfNumbers: $numberOfNumbers)
  • 抱歉 - 我这样展示它是因为实际的类有同一个类的已发布 var。一旦我将 $numOfNumbers 传递给初始化程序 - 它就会给出 self is not initialized 错误 - 如果你想用绑定值初始化一个 var 也是一样的。 --
  • --类似于 - import SwiftUI class MultiplicationPractice:ObservableObject { Binding var numberOfNumbers:Int Published var MulGame:MultiplicationGame = MultiplicationGame(maxNumber: $numberofNumbers)} // - 这是它给出错误的地方

标签: class binding swiftui init


【解决方案1】:

通常您会在 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 var,而是使用上述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)
    }
}

【讨论】:

  • 感谢您抽出时间回复 - 抱歉代码混乱。 - 封面浏览量是主要的(事实) - 这是用户输入 numberOfNumbers 的地方。类 MultiplicationPractice 是我的视图模型,它需要这个 numberofNumbers 才能访问没有视图主体的模型(另一个结构)。所以乘法练习是数据应该流向而不是相反的练习。
  • 这是类 - import SwiftUI class MultiplicationPractice:ObservableObject { Binding var numberOfNumbers:Int Published var MulGame:MultiplicationGame = MultiplicationGame(maxNumber: $numberofNumbers)} // - 这是它给出错误的地方 -
  • 我明白了。因此,您有效地尝试将 numberOfNumbers 从视图传递到视图模型,然后最终从视图模型传递到模型。我会更新我的答案。
  • 这太好了-谢谢。代码编译并工作。我似乎仍然遇到无法超出初始值的问题。例如,如果我将状态的初始值设置为 10 - 然后如果用户输入 11 - 那么我的所有数组索引开始超出范围,而如果用户输入 9 - 那么没有问题并且视图生成正常!
【解决方案2】:

好的,我不太明白你的问题,所以我只列出几个例子,希望其中一个就是你要找的。​​p>


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

【讨论】:

  • 感谢您的回复 - 很抱歉代码混乱。 - 封面浏览量是主要的(事实) - 这是用户输入 numberOfNumbers 的地方。类 MultiplicationPractice 是我的视图模型,它需要这个 numberofNumbers 才能访问没有视图主体的模型(另一个结构)。所以乘法练习是数据应该流向而不是相反的练习。
  • 您的示例 sn-p 正在使用两个视图 - 但我有一个视图和一个类 - 我有一个从用户那里获取值的视图 - 然后这个值需要传递给一个类. (问题主要也是因为作为一个类,它需要初始化所有变量)
  • 恐怕我还是不太明白——也许您可以使用我在示例中提出的相同想法,或者@Samuel-IH 的回答可能对您有所帮助
猜你喜欢
  • 2019-11-03
  • 2021-07-14
  • 1970-01-01
  • 2019-11-03
  • 2021-09-26
  • 2019-11-20
相关资源
最近更新 更多