Исправление
Измените свой блок ForEach
на
ForEach(model.results, id: \.self) { text in
Text(text)
}
Пояснение
Сообщения об ошибках SwiftUI не отображаются.не делаю тебе никаких одолжений.Реальное сообщение об ошибке (которое вы увидите, если вы измените Text(text)
на Text(text as String)
и удалите $
до model.results
), это «Общий параметр ID не может быть выведен».
Другими словами, чтобы использовать ForEach
, элементы, которые вы перебираете, должны быть однозначно идентифицированы одним из двух способов.
- Если элемент является структурой или классом, вы можете сделать егосоответствовать протоколу идентификации, добавив свойство
var id: Hashable
.В этом случае вам не нужен параметр id
. - Другой вариант - указать
ForEach
, что следует использовать в качестве уникального идентификатора, используя параметр id
. Обновление: Вы должны гарантировать, что в вашей коллекции нет повторяющихся элементов.Если два элемента имеют одинаковый идентификатор, любое изменение, внесенное в одно представление (например, смещение), произойдет с обоими представлениями.
В этом случае мы выбрали вариант 2 и сказали ForEach
использоватьСам строковый элемент в качестве идентификатора (\.self
).Мы можем сделать это, так как String соответствует протоколу Hashable.
Как насчет $
?
Большинство представлений в SwiftUI только принимают состояние вашего приложения и выкладывают ихвнешний вид на его основе.В этом примере текстовые представления просто берут информацию, сохраненную в модели, и отображают ее.Но некоторые представления должны иметь возможность обратиться назад и изменить состояние вашего приложения в ответ пользователю:
- Переключатель должен обновить значение Bool в ответ на переключатель
- AСлайдер должен обновить значение Double в ответ на слайд
- TextField должен обновить значение String в ответ на ввод
Способ, которым мы определяем, что должно быть это двасвязь между состоянием приложения и представлением осуществляется с помощью Binding<SomeType>
.Таким образом, Toggle требует, чтобы вы передали ему Binding<Bool>
, для Slider - Binding<Double>
, а для TextField требуется Binding<String>
.
. Именно здесь @State
оболочка свойства (или @Published
внутри @ObservedObject
). Эта оболочка свойства «оборачивает» значение, которое оно содержит в Binding
(наряду с некоторыми другими вещами, чтобы SwiftUI знал, что он обновляет представления при изменении значения).Если нам нужно получить значение, мы можем просто сослаться на myVariable
, но если нам нужно связывание, мы можем использовать сокращение $myVariable
.
Итак, в этом случае ваш исходный код содержал ForEach($model.results)
.Другими словами, вы говорили компилятору: «Итерация по этому Binding<[String]>
», но Binding
- это не коллекция, которую вы можете повторять.Удаление $
говорит: «Итерация по этому [String]», и Array - это коллекция, которую вы можете перебирать.