Использование @State преобразуется в 'self', используемое до инициализации всех сохраненных свойств - PullRequest
0 голосов
/ 03 августа 2020

У меня возникла проблема при использовании свойства @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.swift, из которого вызывается вид Modifier имеет следующий код:

import SwiftUI

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

Я создал этот упрощенный код из моего фактического проекта, что упрощает понимание моей проблемы.

Проблема

проблема в том, что код в функции инициализации приводит к ошибке, и я не знаю, как ее исправить.

Что я пробовал и что мне понадобится

Поскольку это просто упрощенная версия моего фактического кода, мне нужны некоторые требования к моему коду:

  • Mod не может быть вычисляемой переменной
  • Мне почему-то нужен Modifier просматривать как переменную с именем Mod в моем ContentView
  • Когда я удаляю свойство @State, свойство @Binding и $, код работает и приводит к 0 ошибкам. Но мне нужно использовать свойство @State (что, к сожалению, приводит к ошибкам в моем коде)
  • Также должна работать кнопка для скрытия и отображения текста

Я был бы очень благодарен, если кто-нибудь может дать мне подсказку. Я очень ценю вашу помощь!

Ответы [ 3 ]

1 голос
/ 03 августа 2020
Mod = Modifier(showText: _showText.projectedValue)

Вы можете указать let вместо var, если хотите.

1 голос
/ 04 августа 2020

Я действительно нашел способ сделать это. Я не уверен, подойдет ли это, но вот подробности.

Проблема заключалась в том, что SwiftUI, похоже, не позволял устанавливать привязку за пределами body. Таким образом, это решение возвращает новый экземпляр модификатора

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

Протестировано и текст можно скрыть / показать. Надеюсь, это поможет.

0 голосов
/ 03 августа 2020

Использовать представления внутри body context

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