使用@State可以解析为初始化所有存储属性之前使用的“自我”

时间:2020-08-03 18:29:49

标签: ios swift swiftui

使用@State属性时遇到问题。

我的ContentView.swift看起来像这样:

import SwiftUI

struct ContentView: View {
    @State var showText: Bool = true
    
    var Mod: Modifier
    init() {
        Mod = Modifier(showText: $showText) // Throws error -> 'self' used before all stored properties are initialized ('self.Mod' not initialized)
    }
    
    var body: some View {
        VStack {
            if showText == true {
                Text("Hello, World!")
            }
            Mod
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

我的调用Modifier视图的Modifier.swift具有以下代码:

import SwiftUI

struct Modifier: View {
    @Binding var showText: Bool
    
    var body: some View {
        VStack {
            Button("Hide Text") {
                self.showText.toggle()
            }
        }
    }
}

我从实际项目中创建了此简化代码,使我的问题更容易理解。

问题

问题是init函数中的代码导致错误,我不知道如何解决。

我尝试过的东西和需要的东西

因为这只是我实际代码的简化版本,所以我对代码有一些要求:

  • Mod不能是计算变量
  • 在某种程度上,我需要将Modifier视图作为ContentView中名为Mod的变量
  • 当我删除@State属性和@Binding属性以及$时,代码可以正常工作并产生0错误。但是我需要使用@State属性(不幸的是,这会导致我的代码出错)
  • 也可以使用隐藏和显示文本的按钮

如果有人能给我一个提示,我将非常感激。非常感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

Mod = Modifier(showText: _showText.projectedValue)

您可以根据需要将其设置为let而不是var

答案 1 :(得分:1)

我确实找到了一种方法。我不确定是否合适,但这是细节。

问题是SwiftUI似乎不允许在body外部设置Binding。因此,此解决方案返回了Modifier的新实例

struct Modifier: View {
    @Binding var showText: Bool
    
    var body: some View {
        VStack {
            Button("Hide Text") {
                self.showText.toggle()
            }
        }
    }
    
    // this function returns a new instance with the binding
    func bind(to binding: Binding<Bool>) -> Self {
        return Modifier(showText: binding)
    }
}

还有ContentView的代码,我们可以在body内部调用此函数:

struct ContentView: View {
    @State var showText: Bool = true
    var Mod: Modifier
    
    init() {
        Mod = Modifier(showText: .constant(true)) // .constant() gives a placeholder Binding
    }
    
    var body: some View {
        return VStack {
            if showText == true {
                Text("Hello, World!")
            }
            Mod.bind(to: $showText)
        }
    }
}

经过测试,文本可以隐藏/显示。希望对您有所帮助。

答案 2 :(得分:-1)

body上下文中使用视图

struct ContentView: View {
    @State var showText: Bool = true
    
    var body: some View {
        VStack {
            if showText == true {
                Text("Hello, World!")
            }
            Modifier(showText: $showText)
        }
    }
}