Omit items from List without leaving a gap in produced list

I'm working on an app in SwiftUI, Xcode 12.4 / iOS14.

In one view I need to produce a list - but the data for the list is subject to an if / else condition - if a condition is met then the item should be omitted from the list. This works - but the list now has gaps in it from where items have been omitted.

Question is - is there a way to produce a list and omit the gaps or would I need to rebuild a new set of data using the if / else condition and then pass that to the list to avoid gaps ?

I guess you could use filter.

You should better show your code to get better responses.
Update here is the code:

Code Block import SwiftUI
struct CurrencyList: View {
    @EnvironmentObject var FetchedRates:FetchRates
    
    // Info : FetchedRates.faves = ["AUD", "BGN", "CNY", "GBP"] //
    @Environment(\.managedObjectContext) private var viewContext
    
    @FetchRequest(
        entity: CURRENCIES.entity(),
        sortDescriptors: [
            NSSortDescriptor(keyPath: \CURRENCIES.core_Country, ascending: true)
        ])
    
    var items: FetchedResults<CURRENCIES>
    @State var showFavs = false
    
    var body: some View {
        VStack{
            HStack{
                Toggle("Favourites only", isOn: $showFavs)
                
            }
            Divider()
            
        }
        
        List {
            ForEach(items) { record in
                
                HStack{
                    VStack{
                        if FetchedRates.faves.contains(record.core_Code) && showFavs == true {
                            HStack{
                                Text(record.core_Country)
                                
                                Spacer()
                            }
                            HStack(alignment: .center){
                                Text(FLAGCODES[record.core_Code] ?? "")
                                
                                Text(record.core_Code)
                                
                                Text(record.core_Currency_Name)
                                
                                NavigationLink(destination: CurrencyDetail2(RowData: record)) {
                                    
                                }
                            }
                        }
                        else{
                            
                        }
                    }
                }
                .frame(height: 50)
            }
        }
        
        .navigationBarTitle(Text("Exchange Rates"), displayMode: .inline)
        .listStyle(DefaultListStyle())
        .navigationBarItems(trailing:
                                Image(systemName:"antenna.radiowaves.left.and.right").resizable()
                                .foregroundColor(FetchedRates.dataStatus))
    }
}

So basically output of the list is only the currencies within the array of FetchedRates.faves ["AUD","BGN","CNY","GBR"] which is what should happen, but the list has large gaps in it where other currencies which aren't favourited would normally be.
Accepted Answer

Update here is the code:

Thanks for showing your code.
Seems you are using very unique naming rules. Which is forcing readers make much effort to read your code.
You should better improve it, but that's another issue.


the list has large gaps in it where other currencies which aren't favourited would normally be.

That's the expected result from your code, seems SwiftUI in your environment is working correctly.

Why don't you use filter?
Something like this:
Code Block
var body: some View {
VStack{
HStack{
Toggle("Favourites only", isOn: $showFavs)
}
Divider()
}
List {
ForEach(items.filter(myFilter)) { record in
HStack{
VStack{
HStack{
Text(record.core_Country)
Spacer()
}
HStack(alignment: .center){
Text(FLAGCODES[record.core_Code] ?? "")
Text(record.core_Code)
Text(record.core_Currency_Name)
NavigationLink(destination: CurrencyDetail2(RowData: record)) {
}
}
}
}
.frame(height: 50)
}
}
.navigationBarTitle(Text("Exchange Rates"), displayMode: .inline)
.listStyle(DefaultListStyle())
.navigationBarItems(trailing:
Image(systemName:"antenna.radiowaves.left.and.right").resizable()
.foregroundColor(FetchedRates.dataStatus))
}
func myFilter(_ record: CURRENCIES) -> Bool {
return FetchedRates.faves.contains(record.core_Code) && showFavs
}


Thanks, yes that works and is exactly what I was looking for.
I had looked at filter but could never work out a way to implement it for what I wanted (I've only been back at coding for 6 months or so, still getting my head around things)


Omit items from List without leaving a gap in produced list
 
 
Q