#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(...)
, когда вам нужно передать aBinding
для предварительного просмотра — однако это не меняет значения, поэтому эквивалентно тому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()
}
}
}