#swift #foreach #swiftui #view #state
Вопрос:
Я действительно новичок в SwiftUI, поэтому, пожалуйста, будьте нежны. Я пытаюсь передать значение переменной состояния в представление, и я хочу, чтобы переменная состояния увеличивалась внутри цикла ForEach. Вот код, который не работает. Текстовый оператор отлично работает с использованием локальной переменной val, но переменная состояния val остается неизменной. Любая помощь в решении этой проблемы будет признательна. Решения подобных проблем, по-видимому, неприменимы.
struct ContentView: View {
@State
var val: Int = 25
var body: some View {
VStack {
ForEach(Array(stride(from: 10, to: 100, by: 10)), id: .self) { val in
HStack {
Text("(val)")
SubView(val: $val)
}
}
}
}
}
struct SubView: View {
@Binding var val: Int
var body: some View {
Text("(val)")
}
}
Комментарии:
1. Это действительно не имеет смысла в том, что вы сейчас делаете. Что вы ожидаете сделать с
Binding
тем, что вы передадите? Что вы будете с этим делать и как это повлияетContentView
? Я не вижу, что вы будете делать с переменнойval
в@State
переменной.
Ответ №1:
Я думаю, что вы путаетесь с синтаксисом «ForEach», это конструкция, которая принимает коллекцию в качестве входных данных и предоставляет полностью настраиваемое тело, представляющее собой замыкание, которое принимает элемент последовательности в качестве параметра.
Поэтому, когда вы звоните :
ForEach(Array(stride(from: 10, to: 100, by: 10)), id: .self) { val in
Вы не имеете в виду свой :
@State var val: Int = 25
Вы просто зацикливаетесь на коллекции (массиве(Шаг)) и временно ссылаетесь на каждый элемент словом «val», но вы могли использовать любое другое слово, например :
ForEach(Array(stride(from: 10, to: 100, by: 10)), id: .self) { increment in
После этой предпосылки становится ясно, что ваш «val» никогда не меняется, это значение во время выполнения, и правильно, что оба текста остаются неизменными.
Еще одна вещь, которую следует понимать, заключается в том, что ForEach может использоваться только для действий пользовательского интерфейса, вы не можете использовать его для изменения переменной или выполнения кода. Поэтому я рекомендую вам использовать альтернативу, подобную следующей :
struct ContentView: View {
@State
var val: Int = 25
var body: some View {
HStack {
Text("(val)")
SubView(val: $val)
}
.onAppear {
for i in stride(from: 10, to: 100, by: 10) {
val = i
}
}
}
}
Но я не совсем понимаю, какой результат вы хотите получить.
Комментарии:
1. Спасибо за очень полезный ответ. Мое намерение состоит в том, чтобы использовать переменную val для возврата подвида, представляющего строку в большей таблице значений, для построения таблицы результатов, но я все еще нахожусь в SwiftUI и делаю несколько неверных поворотов!
2. Я не думаю, что состояние и привязка являются вашим решением. Состояние похоже на источник, а привязка похожа на динамическую копию, при изменении состояния все привязки автоматически меняются на его значение. Так, например, если вы создаете таблицу со 100 строками, и каждая строка содержит привязку к val, когда val равен 25, все строки равны 25. Если вы увеличите значение val, все строки будут обновлены до одного и того же значения.
3. Спасибо за ваш совет. В итоге я создал функцию, которая возвращала представление, содержимое которого корректировалось переменной, переданной функции, которая была увеличена в цикле foreach. Не уверен, что это лучший способ, но он работает.