Changing swipeActions dynamically in SwiftUI

I am trying to change the swipeAction from "Paid" to "UnPaid" based on payment status and somehow seems to be failing. Error: "The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions"

Appreciate any help

struct ContentView: View {

var data: [Data] = [data1, data2, data3, data4] 
@State var swipeLabel = true

var body: some View {
    let grouped = groupByDate(data)
    List {
        ForEach(Array(grouped.keys).sorted(by: >), id: \.self) { date in 
            let studentsDateWise = grouped[date]!
            Section(header:Text(date, style: .date)) {
                ForEach(studentsDateWise, id:\.self) { item in 
                    HStack {    
                        Text(item.name)
                        padding()
                        Text(item.date, style: .time)
                        if(item.paymentStatus == false) {
                            Image(systemName: "person.fill.questionmark")
                                .foregroundColor(Color.red)
                            
                        } else {
                            Image(systemName: "banknote")
                                .foregroundColor(Color.green)
                        }
                    } // HStack ends here
                    .swipeActions() {
                        if(item.paymentStatus) {
                            Button("Paid"){}
                        } else {
                            Button("UnPaid"){}
                        }
                    }
                } // ForEach ends here... 
            } // section ends here
        } // ForEach ends here
    } // List ends here
} // var ends here
}

1 answer

  • answered 2022-01-25 13:23 malhal

    The body func shouldn't do any grouping or sorting. You need to prepare your data first into properties and read from those in body, e.g. in an onAppear block. Also if your Data is a struct you can't use id: \.self you need to either specify a unique identifier property on the data id:\.myUniqueID or implement the Indentifiable protocol by either having an id property or an id getter that computes a unique identifier from other properties.

    I would suggest separating all this code into small Views with a small body that only uses one or a two properties. Work from bottom up. Then eventually with one View works on an array of dates and another on an array of items that contains the small Views made earlier.

    You should probably also learn that if and foreach in body are not like normal code, those are converted into special Views. Worth watching Apple's video Demystify SwiftUI to learn about structural identity.

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum