使用 @Binding var 初始化 SwiftUI 类
Posted
技术标签:
【中文标题】使用 @Binding var 初始化 SwiftUI 类【英文标题】:Init for a SwiftUI class with a @Binding var 【发布时间】: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) // - 这是它给出错误的地方
【参考方案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 的回答可能对您有所帮助以上是关于使用 @Binding var 初始化 SwiftUI 类的主要内容,如果未能解决你的问题,请参考以下文章
Swift / SwiftUI:如何检查环境 /binding var 是不是为空字符串(.isEmpty 出现构建错误)
为啥在 Swift 中使用惰性 var 初始化时添加框架不显示 UIView
Swift: let 未初始化,但 var 已初始化。为啥? [复制]