【问题标题】:SwiftUI: How do I display multidimensional array as sections in List?SwiftUI:如何将多维数组显示为列表中的部分?
【发布时间】:2023-03-22 02:43:01
【问题描述】:

我有以下对象作为var events = [[EventLog]],我需要遍历每个内部数组并将它们显示在一个部分中。例如,events[0] 可能有 events[0][0].id events[0][1].idevents[0][2].id 作为值,events[1] 可能只有 1 个元素。这是我为参考而构建的对象。

模型对象

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
    }
}

尝试使用

这样做会导致此错误:Referencing initializer 'init(_:content:)' on 'ForEach' requires that '[EventLog]' conform to 'Identifiable' 应该注意的是,多维数组存储在名为landingPageVM 的 ViewModel 上,为简洁起见,此处未引用。然而,它是视图模型的 @Published 属性。

ForEach(landingPageVM.eventLogs) { logs in
            ForEach(logs)) { log in
                Text(log.id.description)
            }
        }

【问题讨论】:

    标签: arrays user-interface multidimensional-array swiftui


    【解决方案1】:

    如果您可以将模型更改为 struct 而不是类,您将更轻松地使用这个(以及 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
    }
    

    如果您因某种原因无法使用class,您仍然可以通过执行以下操作来获得此行为:

    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
        }
    }
    

    hash== 实现的详细信息可能会有所不同。

    【讨论】:

    • 如何将其放入一个部分?从 class 到 struct 的变化肯定会有所作为。你能解释一下为什么吗?另外,想要这些部分,但我不断收到Int does not conform to View 或类似的东西。本质上,该部分的标题可以是 logs.count 以标识每个部分或沿着这些行的内容。
    • Sections 更新——听起来你只是想传递Int 而不是Text
    • Ahhhh 我没有意识到它可以接受这样的观点。甜的!我每天都越来越喜欢 SwiftUI。
    • Re: struct vs class,有了struct,编译器会为你生成更多的合成行为。此外,通过引用传递与按值传递存在巨大差异(这对您来说值得研究)。 SwiftUI 视图倾向于更新查看值类型(即结构)的集合。
    猜你喜欢
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    相关资源
    最近更新 更多