Почему текст не обновляется при использовании @Binding?

#swift #swiftui

#swift #swiftui

Вопрос:

Working Работает, как и ожидалось.

Но использование @Binding в NotWorking примере, похоже, не обновляет элемент Text управления. Почему @Binding версия не работает, чего мне здесь не хватает?

Первоначальный запуск: Первоначальный запуск

После ввода: После ввода

 struct Working: View {
    //Binding from @State updates both controls
    @State private var text = "working"
    
    var body: some View {
        VStack {
            TextField("syncs to label...", text: $text)
            Text($text.wrappedValue)
        }
    }
}
struct NotWorking: View {
    //Using the @Binding only updates the TextField
    @Binding var text: String
    
    var body: some View {
        //This does not works
        VStack {
            TextField("won't sync to label...", text: $text)
            Text($text.wrappedValue)
        }
    }
}

struct Working_Previews: PreviewProvider {
    @State static var text = "not working"
    static var previews: some View {
        VStack {
            Working()
            NotWorking(text: $text)
        }
    }
}
  

Комментарии:

1. Статические @State файлы не работают.

2. Спасибо. Это было в документах или видео или что-то в этом роде? Существует ли общий обходной путь?

Ответ №1:

Статические @State файлы не работают. Это тот факт, что это static означает, что struct Working_Previews при изменении значение не изменяется text , поэтому оно не обновляется.

Мы можем проверить это, изменив значение с a PreviewProvider на фактическое View :

 struct ContentView: View {
    
    @State static var text = "not working"
    
    var body: some View {
        VStack {
            Working()
            NotWorking(text: ContentView.$text)
        }
    }
}
  

Этот код выдает следующее сообщение во время выполнения:

Доступ к значению состояния вне установки в представлении. Это приведет к постоянной привязке начального значения и не будет обновляться.

Комментарии:

1. Спасибо. Так что static var не изменяет struct . Есть ли что-то еще, что я могу сделать, чтобы заставить это работать для предварительного просмотра?

2.@joels я не уверен, было бы просто лучше не использовать static с оболочками свойств SwiftUI. Сделайте что-то более похожее на ваш рабочий пример, где @State находится внутри представления. Другой вариант заключается в том, что вы также можете использовать .constant(...) , когда вам нужно передать a Binding для предварительного просмотра — однако это не меняет значения, поэтому эквивалентно тому static @State , что у вас есть в нерабочем примере (но .constant(...) намного аккуратнее.

3. Я понимаю. Спасибо. Мне понадобится доступ к text свойству из родительских представлений. Вот почему я пытаюсь использовать @Binding вместо @State .

Ответ №2:

Спасибо @George_E. Я определяю @State в представлении оболочки и показываю его для предварительного просмотра. WrapperView Просто отображается элемент управления, который я хочу просмотреть, но он содержит состояние.

Работает

 struct Working_Previews: PreviewProvider {
    //Define the State in a wrapper view
    struct WrapperView: View {
        @State var text = "Preview is now working!!!"
        var body: some View {
            NotWorking(text: $text)
        }
    }

    static var previews: some View {
        VStack {
            Working()
            //Don't display the view that needs the @Binding
            //NotWorking(text: $text)
            //Use the WrapperView that has @State and displays the view I want to preview.
            WrapperView()
        }
    }
}