SwiftUI Jak utworzyć instancję PreviewProvider, gdy View wymaga @ Binding w inicjalizatorze


10

W SwiftUI (Xcode 11.1) mam kilka widoków skonfigurowanych z powiązaniami 2-kierunkowymi (używając @Binding ). Dwukierunkowa aktualizacja działa świetnie.

Jak jednak utworzyć instancję widoku z PreviewProvider?

Na przykład:

struct AddProjectView: View {

    @Binding public var showModal: Bool

    var body: some View {

        return VStack {
            Text("Add Project View")
            Button("Dismiss") {
                self.showModal = false
            }
        }
    }
}

Nie mogę tego zrobić, ponieważ „prawda” nie jest wiązaniem:

struct AddProjectView_Previews: PreviewProvider {
    static var previews: some View {
        AddProjectView(showModal: true)
    }
}

Nie mogę tego zrobić, ponieważ „ Opakowania właściwości nie są jeszcze obsługiwane w przypadku właściwości lokalnych ”:

struct AddProjectView_Previews: PreviewProvider {
    static var previews: some View {
        @Binding var show = true
        return AddProjectView(showModal: $show)
    }
}

Jak to robimy?

Dzięki!!

Odpowiedzi:


15

.constant jest przeznaczony właśnie do tego:

/// Tworzy powiązanie z niezmiennym value.

struct AddProjectView: View {
    @Binding public var showModal: Bool
    var body: some View {
        return VStack {
            Text("Add Project View")
            Button("Dismiss") {
                self.showModal = false
            }
        }
    }
}

struct AddProjectView_Previews: PreviewProvider {
    static var previews: some View {
        AddProjectView(showModal: .constant(true))
    }
}

Doskonały! -- Niesamowite!
drewster

5

Musisz zadeklarować go jako @State w podglądzie.

struct AddProjectView_Previews: PreviewProvider {

     @State static var showModal: Bool = false

     static var previews: some View {
         AddProjectView(showModal: $showModal)
     }
}

Pamiętaj również, że musi być statyczny, ponieważ jest używany w funkcji statycznej.


1
Zachowanie w XCode 11.3 jest w rzeczywistości takie samo jak używanie .constant(false), tzn. Jeśli korzystasz z podglądu na żywo, wartości nie można zmienić.
Fabian Streitel,

4

Jeśli potrzebujesz tylko stałej wartości , użyj .constant(VALUE):

struct YourView_Previews: PreviewProvider {

    static var previews: some View {
        YourView(yourBindingVar: .constant(true))
    }

}

Jeśli potrzebujesz wartości, którą można zmienić w podglądzie na żywo , chciałbym użyć tej klasy pomocnika:

struct BindingProvider<StateT, Content: View>: View {

    @State private var state: StateT
    private var content: (_ binding: Binding<StateT>) -> Content

    init(_ initialState: StateT, @ViewBuilder content: @escaping (_ binding: Binding<StateT>) -> Content) {
        self.content = content
        self._state = State(initialValue: initialState)
    }

    var body: some View {
        self.content($state)
    }
}

Używaj go w ten sposób:

struct YourView_Previews: PreviewProvider {

    static var previews: some View {
        BindingProvider(false) { binding in
            YourView(yourBindingVar: binding)
        }
    }

}

Pozwala to przetestować zmianę powiązania w podglądzie na żywo.


Nie masz pojęcia, jak twoja odpowiedź pomogła mi stworzyć lepszy kod. Stukrotne dzięki. Wciąż uczę się SWIFTUI i BindingProvider, który napisałeś, jest po prostu poza moją ograniczoną szybką wiedzą. Mam wrażenie, czy nie rozumiem w 100%. W każdym razie dzięki.
GrandSteph

Miło, że mogłem pomóc! Tak trzymaj i ucz się dalej: D
Fabian Streitel
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.