SwiftUI Cara instantiate PreviewProvider saat View membutuhkan @Binding in initializer

10

Dengan SwiftUI (Xcode 11.1), saya memiliki beberapa Tampilan yang diatur dengan binding 2 arah (menggunakan @Binding ). Pembaruan dua arah berfungsi dengan baik.

Namun, bagaimana saya bisa membuat tampilan dari PreviewProvider?

Sebagai contoh:

struct AddProjectView: View {

    @Binding public var showModal: Bool

    var body: some View {

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

Saya tidak bisa melakukan ini, karena "benar" bukan Binding:

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

Dan saya tidak dapat melakukan ini karena " Pembungkus properti belum didukung pada properti lokal ":

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

Bagaimana kita melakukan ini?

Terima kasih!!

drewster
sumber

Jawaban:

15

.constant dimaksudkan untuk itu:

/// Membuat ikatan dengan yang abadi 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))
    }
}
superpuccio
sumber
Sempurna! - Luar biasa!
drewster
5

Anda harus mendeklarasikannya sebagai @State pada Pratinjau Anda.

struct AddProjectView_Previews: PreviewProvider {

     @State static var showModal: Bool = false

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

Juga ingat bahwa itu harus statis karena digunakan dalam fungsi statis.

LuLuGaGa
sumber
1
Perilaku dalam XCode 11.3 secara efektif sama dengan menggunakan .constant(false), yaitu jika Anda menggunakan pratinjau langsung, nilainya tidak dapat diubah.
Fabian Streitel
4

Jika Anda hanya membutuhkan nilai konstan , gunakan .constant(VALUE):

struct YourView_Previews: PreviewProvider {

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

}

Jika Anda membutuhkan nilai yang dapat diubah di pratinjau langsung , saya ingin menggunakan kelas penolong ini:

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

Gunakan seperti ini:

struct YourView_Previews: PreviewProvider {

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

}

Ini memungkinkan Anda menguji perubahan penjilidan dalam pratinjau langsung.

Fabian Streitel
sumber
Anda tidak tahu bagaimana jawaban Anda membantu saya menghasilkan kode yang lebih baik. Terima kasih banyak. Saya masih belajar SWIFTUI dan BindingProvider yang Anda tulis hanya melampaui pengetahuan cepat saya. Saya mengerti jika tetapi tidak mengerti 100%. Bagaimanapun, terima kasih.
GrandSteph
Senang untuk membantu! Terus dan terus belajar: D
Fabian Streitel