Как передать переменную состояния во второе представление после ее увеличения в первом представлении в цикле foreach

#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. Не уверен, что это лучший способ, но он работает.