Search code examples
iosswiftuivisibilityswiftui-list

Dynamically Hiding Empty Sections of List in SwiftUI


I have a dynamic SwiftUI List that populates utilizing an enum for States. Then it cycles through my dictionary of data looking for a state match to display data. All of this works perfectly. What I am looking to do but struggling with is to hide those states that are then empty.

The section of code in question is:

@State private var bucketList: [BucketListItems] = []
...
List {
    ForEach(USStates.allCases) { states in
        Section {
            ForEach (bucketList) { item in
                if (item.state == states.abrev) {
                    NavigationLink(destination: ItemDetails(blItem: item.recordID)) {
                        Label(item.name, systemImage: item.monogram)
                                    .frame(height: 50)
                            .foregroundColor(item.completedate=="0000-00-00" ? .white : .red)
                    }
                }
            }
        } header: {
            Text(states.rawValue)
        }
    }
}

When a state doesn't have a match, then I want that entire section to be hidden.

Some additional relevant code:

struct BucketListItems: Encodable, Decodable, Identifiable, Hashable {
    let id = UUID()
    var recordID: Int
    var url: String
    var user: Int
    var name: String
    var category: String
    var state: String
    var latitude: String
    var longitude: String
    var description: String
    var completedate: String
}

Solution

  • Since you do not show a minimum example code (ie, we have to guess what USStates.allCases are etc...),

    you could try these approaches, assuming that states is an [String] type.

    One is to test the state before the Section, such as:

     if !bucketList.filter({states.contains($0.state)}).isEmpty {
         Section { ....
    
     }
     
    

    Another approach is to do the filtering in the ForEach, such as:

     ForEach(bucketList.filter({states.contains($0.state)})) { item in
        // ...
     }