Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI: How do I display multidimensional array as sections in List?

I have the following object as a var events = [[EventLog]] and I need to loop through each inner-array and display them in a section. For example, events[0] might have events[0][0].id events[0][1].id and events[0][2].id as values and events[1] may only have 1 element. This is the object that I've built for reference.

Model Object

class EventLog: Identifiable  {
    let id: UUID
    let ipAddress: String
    let date: String
    let getMethod: String
    let statusCode: String
    let secondStatusCode: String
    let versionInfo: String
    
    init(ipAddress: String, date: String, getMethod: String, statusCode: String, secondStatusCode: String, versionInfo: String ){
        self.id = UUID()
        self.ipAddress = ipAddress
        self.date = date
        self.getMethod = getMethod
        self.statusCode = statusCode
        self.secondStatusCode = secondStatusCode
        self.versionInfo = versionInfo
    }
}

Attempts At Using

Doing it this way results in this error: Referencing initializer 'init(_:content:)' on 'ForEach' requires that '[EventLog]' conform to 'Identifiable' It should be noted that the multidimensional array is stored on a ViewModel named landingPageVM which is not referenced here for the sake of brevity. It is however an @Published property of the view model.

ForEach(landingPageVM.eventLogs) { logs in
            ForEach(logs)) { log in
                Text(log.id.description)
            }
        }
like image 375
xTwisteDx Avatar asked Dec 13 '25 12:12

xTwisteDx


1 Answers

If you can change your model to a struct instead of a class, you'll have an easier time with this (and a lot of other things in SwiftUI):

struct ContentView : View {
    @State var eventLogs : [[EventLog]] = []
    
    var body: some View {
        List {
            ForEach(eventLogs, id: \.self) { logs in
                Section(header: Text("\(logs.count)")) {
                    ForEach(logs) { log in
                        Text(log.id.description)
                    }
                }
            }
        }
    }
}

struct EventLog: Identifiable, Hashable  {
    let id: UUID
    let ipAddress: String
    let date: String
    let getMethod: String
    let statusCode: String
    let secondStatusCode: String
    let versionInfo: String
}

If you're stuck using a class for some reason, you can still get this behavior by doing something like:

extension EventLog : Hashable, Equatable {
    func hash(into hasher: inout Hasher) {
        hasher.combine(id) //etc
    }
    
    static func == (lhs: EventLog, rhs: EventLog) -> Bool {
        lhs.id == rhs.id && lhs.ipAddress == rhs.ipAddress //etc
    }
}

Details of the hash and == implementations may vary.

like image 194
jnpdx Avatar answered Dec 15 '25 05:12

jnpdx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!