swiftuiswiftui-list

Why does using .listRowBackground in only one instance gives me a compiler error, while other instances do not?


Trying to add a clear background to all cells, so I applied listRowBackground(Color.clear) to each List. All worked, except the second instance (commented out in the code below).

Uncommenting it out gives me the error:

Compiling failed: the compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

Despite my efforts I can't seem to determine how I am using it differently than the other two instance which give me no errors.

*Update, I replaced that List section with the much simpler one, listed down below my code. And it still gave the same error using listRowBackground.

import SwiftUI
    
    struct ContentView: View {
        @Environment(\.dismiss) var dismiss
        
        struct ExcelTuple: Hashable {
            var sheetName: String
            var column: String
            var row: Int
            var value: String
            var use = true
        }
        
        @State var selectedSheet     = "Sheet1"
        @State var selectedColumn   = ""
        @State var filteredExcel    : [ExcelTuple] = []
        @State var values           : [String] = []
        
        
        var body: some View {
            ZStack {
                Color(.gray)
                    .ignoresSafeArea()
                
    
                VStack {
    
                    HStack {
                        Spacer()
                        Button{
                            
                        } label:
                        {
                            Image(systemName: "xmark.circle.fill")
                                .foregroundColor(.black)
                                .font(.system(size: 30))
                                .padding(.trailing, 30)
                        }
                    }
    
                    
                    HStack {
                        VStack {
                            Text("Sheet")
                                .textCase(.uppercase)
                                .font(.footnote)
                            
                            List {
                                ForEach(sheets, id: \.self) { sheet in
                                    Text(sheet)
                                        .padding(10)
                                        .frame(maxWidth: .infinity)
                                        .background(selectedSheet == sheet ? Color.blue : Color.white)
                                        .foregroundColor(selectedSheet == sheet ? Color.white : Color.black)
                                        .cornerRadius(3)  // Optional: Rounded corners for styling
                                        .onTapGesture {
                                            selectedSheet = sheet // Update the selected item when clicked
                                            filteredExcel = excelData.filter { $0.sheetName == selectedSheet }
                                            if let firstColumn = filteredExcel.first(where: { !$0.column.isEmpty }) {
                                                selectedColumn = firstColumn.column
                                            }
                                        }
                                }
                                .listRowBackground(Color.clear)
                            }
                            .listStyle(PlainListStyle())
                            .frame(maxHeight: 150)
                            .cornerRadius(10)
                            .padding()
                        }
                        
                        VStack {
                            Text("Column")
                                .textCase(.uppercase)
                                .font(.footnote)
                            List {
                                let uniqueColumnsSet = Set(excelData.filter { $0.sheetName == selectedSheet }.map { $0.column })
                                
                                let uniqueColumns = Array(uniqueColumnsSet).sorted() // Convert Set back to Array
                                
                                ForEach(uniqueColumns, id: \.self) { curColumn in
                                    Text(curColumn)
                                        .padding(10)
                                        .frame(maxWidth: .infinity)
                                        .background(selectedColumn == curColumn ? Color.blue : Color.white)
                                        .foregroundColor(selectedColumn == curColumn ? Color.white : Color.black)
                                        .cornerRadius(3)
                                        .onTapGesture {
                                            selectedColumn = curColumn
                                            filteredExcel = excelData.filter { $0.sheetName == selectedSheet && $0.column == selectedColumn }
                                        }
                                }
                                //.listRowBackground(Color.clear)
                            }
                            .listStyle(PlainListStyle())
                            .frame(maxHeight: 150)
                            .background(Color.clear)
                            .cornerRadius(10)
                            .padding()
                            
                        }
                        
                    }
                    
                    if !selectedColumn.isEmpty {
                        VStack {
                            List {
                                ForEach(filteredExcel, id: \.self) { entry in
                                    Text(entry.value)
                                        .frame(maxWidth: .infinity, alignment: .leading)
                                        .background(entry.use == false ? .red.opacity(0.30) : .green.opacity(0.30))
                                        .cornerRadius(3)
                                }
                                .listRowBackground(Color.clear)
                            }
                            .listStyle(PlainListStyle())
                            .background(Color.clear)
                            .cornerRadius(10)
                            .padding()
                            
                            Spacer()
                            
                            HStack {
                                Button {
                                    for index in excelData.indices {
                                        if excelData[index].sheetName == selectedSheet && excelData[index].column == selectedColumn {
                                            excelData[index].use = true
                                        }
                                    }
                                    filteredExcel = excelData.filter { $0.sheetName == selectedSheet && $0.column == selectedColumn }
                                } label : {
                                    Text("Use")
                                        .font(.title)
                                        .minimumScaleFactor(0.5)
                                        .foregroundColor(.white)
                                        .padding(10)
                                        .frame(width: 150, height: 75, alignment: .center)
                                        .background(.green.opacity(0.5))
                                        .cornerRadius(10)
                                }
                                
                                Button {
                                    for index in excelData.indices {
                                        if excelData[index].sheetName == selectedSheet && excelData[index].column == selectedColumn {
                                            excelData[index].use = false
                                        }
                                    }
                                    filteredExcel = excelData.filter { $0.sheetName == selectedSheet && $0.column == selectedColumn }
                                } label : {
                                    Text("Do NOT Use")
                                        .font(.title)
                                        .minimumScaleFactor(0.5)
                                        .foregroundColor(.white)
                                        .padding(10)
                                        .frame(width: 150, height: 75, alignment: .center)
                                        .background(.red.opacity(0.5))
                                        .cornerRadius(10)
                                }
                            }
                            .frame(maxWidth: .infinity)
                            .padding(.horizontal, 16)
                            
                            Spacer()
                        }
                    }
                    
                    Button {
                    } label : {
                        Text("Save")
                            .font(.title)
                            .minimumScaleFactor(0.5)
                            .lineLimit(1)
                            .foregroundColor(.white)
                            .padding(10)
                            .frame(width: 200, height: 75, alignment: .center)
                            .background(.blue.opacity(0.5))
                            .cornerRadius(10)
                    }
                    
                    
                    Spacer()
                    
                }
                .onAppear {
                    
                    excelData.sort { (tuple1, tuple2) -> Bool in
                        // First, compare by sheetName
                        if tuple1.sheetName != tuple2.sheetName {
                            return tuple1.sheetName < tuple2.sheetName
                        }
                        
                        // Second, compare by column alphabetically
                        if tuple1.column != tuple2.column {
                            return tuple1.column < tuple2.column
                        }
                        
                        // Finally, compare by row numerically
                        return tuple1.row < tuple2.row
                    }
                    
                    
                    filteredExcel = excelData.filter { $0.sheetName == selectedSheet }
                    
                    if let firstColumn = filteredExcel.first(where: { !$0.column.isEmpty }) {
                        selectedColumn = firstColumn.column
                    }
                    
                }
                
    
                
            }
        }
        //
        
        
        
        @State var sheets: [String] = ["Sheet1", "Sheet2", "Sheet3 and stuff", "Sheet4", "Sheet5", "Sheet6", "Sheet7"]
        
        @State var excelData: [ExcelTuple] = [
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 1, value: "Smith"),
            ExcelTuple(sheetName: "Sheet1", column: "B", row: 2, value: "32"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 2, value: "Johnson"),
            ExcelTuple(sheetName: "Sheet1", column: "D", row: 2, value: "45"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 2, value: "Miller"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 3, value: "27"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 3, value: "Taylor"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 3, value: "29"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 4, value: "Brown"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 4, value: "33"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 4, value: "45"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 5, value: "Miller"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 5, value: "38"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 5, value: "44"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 6, value: "Ferguson"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 6, value: "25"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 6, value: "33"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 7, value: "Williams"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 7, value: "41"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 7, value: "54"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 8, value: "Jones"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 8, value: "32"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 8, value: "29"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 9, value: "White"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 9, value: "37"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 9, value: "41"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 10, value: "Taylor"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 10, value: "30"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 10, value: "28"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 11, value: "Harris"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 11, value: "35"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 11, value: "33"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 12, value: "Lewis"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 12, value: "41"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 12, value: "47"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 13, value: "Walker"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 13, value: "29"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 13, value: "26"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 14, value: "Adams"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 14, value: "35"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 14, value: "37"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 15, value: "Scott"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 15, value: "31"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 15, value: "39"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 16, value: "Nelson"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 16, value: "40"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 16, value: "45"),
            ExcelTuple(sheetName: "Sheet1", column: "A", row: 17, value: "Carter"),
            ExcelTuple(sheetName: "Sheet1", column: "C", row: 17, value: "33"),
            ExcelTuple(sheetName: "Sheet1", column: "E", row: 17, value: "41")
        ]
    
    }
    
    
    #Preview {
        
        ContentView()
    }

Update Still crashes using this slimmed down List

List {
   ForEach(filteredExcel, id: \.self) { entry in
      Text(entry.value)
   }
   .listRowBackground(.clear)
}

Solution

  • The modifier .lstRowBackground takes a View as parameter, see listRowBackground(_:).

    This means, .clear is not recognized, because .clear is not a static property of View. You need to specify the type of view too:

    .listRowBackground(Color.clear)
    

    For the original error, where you were actually using Color.clear, it is probably just a case of too much for the compiler to take in. When you comment out some of the other blocks, it works. So you might want to follow the suggestion in the error and try breaking up the expression into distinct sub-expressions.