SwiftUI Як інстанціювати PreviewProvider, коли для перегляду потрібен @Binding в ініціалізаторі


10

За допомогою SwiftUI (Xcode 11.1) у мене з’явилися декілька представлень із двосторонніми прив'язками (за допомогою @Binding ). Двостороннє оновлення працює чудово.

Однак як я можу створити подання з програми PreviewProvider?

Наприклад:

struct AddProjectView: View {

    @Binding public var showModal: Bool

    var body: some View {

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

Я не можу цього зробити, тому що "true" не є Пов'язуванням:

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

І я не можу цього зробити, оскільки " обгортки власності ще не підтримуються на локальних ресурсах ":

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

Як ми це робимо?

Дякую!!

Відповіді:


15

.constant призначений саме для цього:

/// Створює зв'язок із незмінним 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))
    }
}

Ідеально! - Дивовижно!
малюнок

5

Ви повинні оголосити це як @State на попередньому перегляді.

struct AddProjectView_Previews: PreviewProvider {

     @State static var showModal: Bool = false

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

Також пам’ятайте, що він повинен бути статичним, оскільки він використовується в статичному функціоналі.


1
Поведінка в XCode 11.3 фактично така ж, як і при використанні .constant(false), тобто якщо ви використовуєте попередній перегляд, значення не можна змінити.
Fabian Streitel

4

Якщо вам потрібно лише постійне значення , використовуйте .constant(VALUE):

struct YourView_Previews: PreviewProvider {

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

}

Якщо вам потрібне значення, яке можна змінити в режимі попереднього перегляду , я люблю використовувати цей допоміжний клас:

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

Використовуйте його так:

struct YourView_Previews: PreviewProvider {

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

}

Це дозволяє перевірити зміну прив’язки в режимі попереднього перегляду.


Ви не знаєте, як ваша відповідь допомогла мені створити кращий код. Завдяки мільйонів. Я все ще навчаюсь SWIFTUI та BindingProvider, який ви написали, - це лише мої обмежені швидкі знання. Я розумію, якщо, але не розумію на 100%. Все одно, дякую.
GrandSteph

Радий допомогти! Продовжуйте та продовжуйте вчитися: D
Fabian Streitel
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.