SwiftUI List с ForEach работает в одном VStack, но не во втором

Я совершенно не понимаю, почему список, который я пытаюсь создать (с ForEach) в SwiftUI, ведет себя именно так. У меня есть ObservedObject, который я проверил в инспекторе, содержит ожидаемые мной данные. В первом VStack я могу создать список с помощью ForEach, и он отлично выводит. Во втором VStack я не получаю вывода данных.

struct WorkoutPreview: View {
  @Environment(\.managedObjectContext) var managedObjectContext
  @ObservedObject var workoutSessionExercises: WorkoutSessionExercises

  var body: some View {
    NavigationView {
      VStack {
        Text("Welcome to your workout! Below are the exercises and bands you've selected for each.")
          .padding()
        Text("We found \(workoutSessionExercises.workoutExercises.count) workouts.")
          .padding()

        // This List (with ForEach) works fine and produces output.
        List {
          ForEach(0..<workoutSessionExercises.workoutExercises.count) { index in
            Text(self.workoutSessionExercises.workoutExercises[index].exerciseName)
          }
        }
      }

      // The exact same List (with ForEach) in this VStack produces no results.
      VStack {
        List {
          ForEach(0..<workoutSessionExercises.workoutExercises.count) { index in
            Text(self.workoutSessionExercises.workoutExercises[index].exerciseName)
          }
        }
      }

      Spacer()
    }
  }
}

person Chris Dressler    schedule 17.06.2020    source источник


Ответы (1)


проблема в том, что у вас есть 2 виртуальных стека, которые не расположены один под другим в представлении, поэтому вы не можете увидеть второй список. Чтобы решить вашу проблему, оберните ваши VStacks в другой VStack, например:

var body: some View {
    NavigationView {
        VStack {   //  <------
            VStack {
                Text("Welcome to your workout! Below are the exercises and bands you've selected for each.").padding()
                Text("We found \(workoutSessionExercises.workoutExercises.count) workouts.").padding()
                // This List (with ForEach) works fine and produces output.
                List {
                    ForEach(0..<workoutSessionExercises.workoutExercises.count) { index in
                        Text(self.workoutSessionExercises.workoutExercises[index].exerciseName)
                    }
                }
            }
            // The exact same List (with ForEach) in this VStack produces no results.
            VStack {
                List {
                    ForEach(0..<workoutSessionExercises.workoutExercises.count) { index in
                        Text(self.workoutSessionExercises.workoutExercises[index].exerciseName)
                    }
                }
            }
            Spacer()
        }         //  <------
    }
}
person workingdog    schedule 17.06.2020
comment
Спасибо за это, он сработал, заключив их обоих в VStack. Можете ли вы помочь мне понять, почему два VStack элемента на одном уровне не могут получить доступ к одному и тому же объекту? Меня смущает то, что они оба живут на одном уровне иерархии, но только первый может это увидеть. - person Chris Dressler; 17.06.2020
comment
NavigationView должен охватывать общий контейнер, например; List, ScrollView, VStack, HStack, Form и т. Д. В противном случае вы получите проблему, с которой столкнулись. Почему я действительно не знаю. Документация Apple не объясняет. Чтобы получить два представления одно за другим по вертикали, они должны быть в VStack. Нет ничего плохого в том, что ваши списки обращаются к объектам workoutExercises. Проблема остается той же самой, даже если вместо этого вы используете Text (...) или любые другие представления. Где отображаются эти представления, я не знаю, я предполагаю, что отображается только первое, а остальные игнорируются. - person workingdog; 18.06.2020