Home > Net >  Can iterate through an array with forEach, but not with List
Can iterate through an array with forEach, but not with List

Time:07-01

I have an array of notes (viewModel.list) that I would like to display in a List. All notes conform to Identifiable.

When I use ForEach, all notes appear just fine:

   ForEach(viewModel.list){ note in
         NoteView(namespace:namespace, note: note)
   }

But if I change this to a List no objects appear:

List(viewModel.list){ note in
    NoteView(namespace:namespace, note: note)
}

The same thing happens if I embed the ForEach in a List

  List{
      ForEach(viewModel.list){ note in
          NoteView(namespace:namespace, note: note)
      }
  }

I want to use a List because I would like to add a swipeAction to every NoteView which can only be used in Lists. Is there any reason this behavior is happening?

UPDATE: I have uploaded a reproducible example below and believe it has something to do with embedding the List in a ScrollView. If I remove the ScrollView, this code works fine, but nothing shows up with it.

import SwiftUI

struct Note: Identifiable {
    var id = UUID()
    var content: String = ""
}
var notes = [
    Note(content: "Lorem ipsum dolor sit amet, consectet adipiscing elit. Condimentum quisque id vitae convallis dignissim pharetra nisl est creatus"),
    Note(content: "Mauris ac tempor libero, non eleifend lectus. Mauris eu hendrerit nunc. Donec at ante mauris. Duis ac elit purus. Mauris ullamcorper mi."),
    Note(content: "Lorem ipsum dolor sit amet, consectet adipiscing elit. Condimentum quisque id vitae convallis dignissim pharetra nisl est creatus"),
    Note(content: "Mauris ac tempor libero, non eleifend lectus. Mauris eu hendrerit nunc. Donec at ante mauris. Duis ac elit purus. Mauris ullamcorper mi.")
]


struct ContentView: View {
    var body: some View {
        ScrollView {
            List(notes){ note in
                NoteView(note: note)
                    .padding(.bottom)
            }
        }
    }
}

struct NoteView: View {
    var note: Note = notes[0]
  
    var body: some View {
        Text(note.content)
    }
    
}

CodePudding user response:

Just remove List from ScrollView - it is scrollable itself.

struct ContentView: View {
    var body: some View {
        List(notes){ note in
            NoteView(note: note)
                .padding(.bottom)
        }
    }
}

*the reason of the issue is that List wants to take parent size to expand, but ScrollView does not have own size and expects from content a size that needs to be scrolled, result is obvious - cycling conflict - to do not crash/hang in cycling SwiftUI breaks layout - output is empty.

CodePudding user response:

List is not showing because List infer it size from its parent View. So when you embed it inside something like Scrollview that have dynamic height, it can't infer it size correctly.

Also List behaves like a UIScrollView (an arbitrarily long scrollable view of views).

So no need to wrap List inside scrollview.

struct ContentView: View {
    var body: some View {
       // ScrollView {
            List(notes){ note in
                NoteView(note: note)
                    .padding(.bottom)
            }
        // }
    }
}
  • Related