Search code examples
swiftswiftui

SwiftUI order different structs within view


I have 2 different structures with many different variables, but each struct has a date variable. I want to present both arrays in a list in SwiftUI in order based on date. How can I combine two arrays of different structs into one then order them based on date?

struct Struct1: Identifiable, DateSortable {
    let id = UUID()
    let date: Date
    let property1: String // Add other properties specific to Struct1
}

struct Struct2: Identifiable, DateSortable {
    let id = UUID()
    let date: Date
    let property2: Int // Add other properties specific to Struct2
}

struct ContentView: View {
    let structArray: [Struct2] = [
        Struct2(date: Date(), property2: 10), // Example data
        Struct2(date: Date().addingTimeInterval(86400), property2: 20), // Example data
        Struct2(date: Date().addingTimeInterval(172800), property2: 30) // Example data
    ]
    
    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 10) {
                ForEach(structArray) { item in
                    VStack(alignment: .leading) {
                        Text("ID: \(item.id)")
                        Text("Date: \(item.date)")
                        Text("Property2: \(item.property2)")
                    }
                    .padding()
                    .background(Color.gray.opacity(0.2))
                    .cornerRadius(10)
                }
            }
            .padding()
        }
    }
}


Solution

  • Much less code than in another answer :)

    struct ContentView: View {
        let myData: [MyWrapper] = [
            MyWrapper(date: Date(), data: Struct1(property1: "hello")),
            MyWrapper(date: Date().addingTimeInterval(86400), data: Struct2(property2: 10)),
            MyWrapper(date: Date().addingTimeInterval(172800), data: Struct2(property2: 30))
        ]
        // !!!ORDER!!!
        .sorted( by: { $0.date < $1.date } )
        
        var body: some View {
            ScrollView {
                VStack(alignment: .leading, spacing: 10) {
                    ForEach(myData) { item in
                        VStack(alignment: .leading) {
                            Text("ID: \(item.id)")
                            Text("Date: \(item.date)")
                            
                            if let tmp = item.data as? Struct1 {
                                Text("Property1: \(tmp.property1)")
                            }
                            
                            if let tmp = item.data as? Struct2 {
                                Text("Property2: \(tmp.property2)")
                            }
                        }
                        .padding()
                        .background(Color.gray.opacity(0.2))
                        .cornerRadius(10)
                    }
                }
                .padding()
            }
        }
    }
    
    struct MyWrapper: Identifiable  {
        var id = UUID()
        var date: Date
        var data: any MyData
    }
    
    protocol MyData { }
    
    struct Struct1: MyData {
        let property1: String
    }
    
    struct Struct2: MyData {
        let property2: Int
    }
    

    enter image description here