SwiftUI Как создать экземпляр PreviewProvider, когда View требует @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
            }
        }
    }
}

Я не могу этого сделать, потому что «истина» не является обязательной:

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

как нам это сделать?

Спасибо!!

drewster
источник

Ответы:

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))
    }
}
superpuccio
источник
Отлично! -- Потрясающие!
Дрюстер
5

Вы должны объявить его как @State в вашем предварительном просмотре.

struct AddProjectView_Previews: PreviewProvider {

     @State static var showModal: Bool = false

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

Также помните, что он должен быть статическим, так как он используется в статической функции.

LuLuGaGa
источник
1
Поведение в XCode 11.3 фактически такое же, как при использовании .constant(false), т. Е. Если вы используете предварительный просмотр в реальном времени, значение не может быть изменено.
Фабиан Штрайтель
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
Рад помочь! Продолжайте в том же
духе