【问题标题】:Swift: Date sorting EKEvents after fetching from EKEventStore into tableView dataSwift:从 EKEventStore 获取到 tableView 数据后对 EKEvents 进行日期排序
【发布时间】:2018-08-22 16:12:45
【问题描述】:

简介

上下文:

我正在开发一个小应用程序,我在其中使用 EKEventStore 来获取用户事件。我正在获取接下来 10 天(从用户打开应用程序时开始)的所有 EKEvents,并将它们存储到 EKEvents 数组中。然后我想对它们进行排序(见下文)并将它们用作我的 tableView 日历的数据。

问题:

  • 我想要数组的以下结构:var allDayEvents : [[EKEvent]]?var dateIntervalEvents : [[EKEvent]]?。其中有一个静态 11 索引 (0-10)。

  • 我相信我正在填充的代码比它必须的要多得多。对于我和性能而言,必须有一种更快的方法。

问题:

  • 如何有效地将 EventStore 查询中获取的事件排序为 allDayEventsdateIntervalEvents 的语法?
    1. 我需要对日期进行排序,以便最早在数组的每个部分中排在第一位。

tableView结构说明:

  1. 我有 11 个部分对应于接下来的 11 天。 (所以是11段的静态值)
  2. 我想显示该部分提供的日期的事件。
  3. 此外,并非全天事件的事件将首先显示在一个单元格类型的部分中,然后将全天事件显示在另一个单元格类型中。
  4. 为我的数据中的以下语法留出空间:dateIntervalEvents[indexPath.section][indexPath.row]allDayEvents[indexPath.section][indexPath.row]

代码:

  • 我的 fetch 方法。

        var allDayEvents : [EKEvent]?
        var dateIntervalEvents : [EKEvent]?
    
        private func getEventsFromCalendarStore() {
    
            let eventStore = EKEventStore()
            var fetchedEvents : [EKEvent]?
            //simulator? either way wrong dates are fetched
            guard let startDate = Calendar.current.date(byAdding: .day, value: -1, to: Date()) else { return }
            guard let endDate = Calendar.current.date(byAdding: .day, value: 10, to: startDate) else { return }
    
            let eventPredicate = eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: userCalendars)
            fetchedEvents = eventStore.events(matching: eventPredicate)
    
            //Basically how to sort fetchedEvents to get the required structure of my array.
    
        }
    
  • 我对数组排序的尝试:

    private func getEventsFromCalendarStore() {
    
         let eventStore = EKEventStore()
         var fetchedEvents : [EKEvent] = []
         var allDayers : [EKEvent] = []
         var dateIntervalls : [EKEvent] = []
    
        var allDay1 : [EKEvent] = []
         var allDay2 : [EKEvent] = []
         var allDay3 : [EKEvent] = []
         var allDay4 : [EKEvent] = []
         var allDay5 : [EKEvent] = []
         var allDay6 : [EKEvent] = []
         var allDay7 : [EKEvent] = []
         var allDay8 : [EKEvent] = []
         var allDay9 : [EKEvent] = []
         var allDay10 : [EKEvent] = []
         var allDay11 : [EKEvent] = []
    
         var dIDay1 : [EKEvent] = []
         var dIDay2 : [EKEvent] = []
         var dIDay3 : [EKEvent] = []
         var dIDay4 : [EKEvent] = []
         var dIDay5 : [EKEvent] = []
         var dIDay6 : [EKEvent] = []
         var dIDay7 : [EKEvent] = []
         var dIDay8 : [EKEvent] = []
         var dIDay9 : [EKEvent] = []
         var dIDay10 : [EKEvent] = []
         var dIDay11 : [EKEvent] = []
    
         guard let startDate = Calendar.current.date(byAdding: .day, value: -1, to: Date()) else { return }
         guard let endDate = Calendar.current.date(byAdding: .day, value: 10, to: startDate) else { return }
    
         let eventPredicate = eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: userCalendars)
    
         //getting all events and sorting them in date order.
         fetchedEvents = eventStore.events(matching: eventPredicate).sorted(by: { (e1 : EKEvent, e2 : EKEvent) -> Bool in
             return e1.compareStartDate(with: e2) == .orderedAscending
         })
    
         //This cant be best practice of sorting it the following way?
         print(fetchedEvents)
    
         for event in fetchedEvents {
    
             if event.isAllDay == true {
                 allDayers.append(event)
             } else {
               dateIntervalls.append(event)
             }
         }
    
         for event in dateIntervalls {
    
             if event.startDate == startDate {
                 dIDay1.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 dIDay2.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 dIDay3.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 dIDay4.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 dIDay5.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 dIDay6.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 dIDay7.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 dIDay8.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 dIDay9.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 dIDay10.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 dIDay11.append(event)
             }
    
         }
    
         for event in allDayers {
             if event.startDate == startDate {
                 allDay1.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 allDay2.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 allDay3.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 allDay4.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 allDay5.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 allDay6.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 allDay7.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 allDay8.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 allDay9.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 allDay10.append(event)
             } else if event.startDate == Calendar.current.date(byAdding: .day, value: 1, to: startDate) {
                 allDay11.append(event)
             }
         }
    
         allDayEvents?.insert(allDay1, at: 0)
         allDayEvents?.insert(allDay2, at: 1)
         allDayEvents?.insert(allDay3, at: 2)
         allDayEvents?.insert(allDay4, at: 3)
         allDayEvents?.insert(allDay5, at: 4)
         allDayEvents?.insert(allDay6, at: 5)
         allDayEvents?.insert(allDay7, at: 6)
         allDayEvents?.insert(allDay8, at: 7)
         allDayEvents?.insert(allDay9, at: 8)
         allDayEvents?.insert(allDay10, at: 9)
         allDayEvents?.insert(allDay11, at: 10)
    
         dateIntervalEvents?.insert(dIDay1, at: 0)
         dateIntervalEvents?.insert(dIDay2, at: 1)
         dateIntervalEvents?.insert(dIDay3, at: 2)
         dateIntervalEvents?.insert(dIDay4, at: 3)
         dateIntervalEvents?.insert(dIDay5, at: 4)
         dateIntervalEvents?.insert(dIDay6, at: 5)
         dateIntervalEvents?.insert(dIDay7, at: 6)
         dateIntervalEvents?.insert(dIDay8, at: 7)
         dateIntervalEvents?.insert(dIDay9, at: 8)
         dateIntervalEvents?.insert(dIDay10, at: 9)
         dateIntervalEvents?.insert(dIDay11, at: 10)
    
    }
    

你会如何处理这种数组结构的排序?

感谢您阅读我的帖子。

【问题讨论】:

    标签: ios swift sorting calendar eventkit


    【解决方案1】:

    首先,去掉你的两组 11 个数组。将每个替换为嵌套数组。

    接下来,在填充 allDayersdateIntervals 之后,您应该对它们进行排序。

    然后就可以对两个数组中的每个事件进行迭代,计算与开始日期相差的天数,更新对应的嵌套数组。

    private func getEventsFromCalendarStore() {
        guard let startDate = Calendar.current.date(byAdding: .day, value: -1, to: Date()) else { return }
        guard let endDate = Calendar.current.date(byAdding: .day, value: 10, to: startDate) else { return }
    
        let eventStore = EKEventStore()
        var fetchedEvents : [EKEvent] = []
        var allDayers : [EKEvent] = []
        var dateIntervals : [EKEvent] = []
    
        let eventPredicate = eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: userCalendars)
    
        //getting all events and sorting them in date order.
        fetchedEvents = eventStore.events(matching: eventPredicate).sorted(by: { (e1 : EKEvent, e2 : EKEvent) -> Bool in
            return e1.compareStartDate(with: e2) == .orderedAscending
        })
    
        //This cant be best practice of sorting it the following way?
        print(fetchedEvents)
    
        for event in fetchedEvents {
            if event.isAllDay == true {
                allDayers.append(event)
            } else {
                dateIntervals.append(event)
            }
        }
    
        allDayers.sort { $0.startDate < $1.startDate  }
        dateIntervals.sort { $0.startDate < $1.startDate  }
    
        var groupedAllDayers = Array(repeating: [EKEvent](), count: 11)
        var groupedIntervals = Array(repeating: [EKEvent](), count: 11)
    
        for event in dateIntervals {
            let days = Calendar.current.dateComponents([.day], from: startDate, to: event.startDate).day!
            groupedIntervals[days].append(event)
        }
        for event in allDayers {
            let days = Calendar.current.dateComponents([.day], from: startDate, to: event.startDate).day!
            groupedAllDayers[days].append(event)
        }
    }
    

    最后,groupedAllDayersgroupedIntervals 将包含您的两组事件,每组按从startDate 到事件的startDate 的天数分组。

    【讨论】:

    • 由于fetchedEvents (显然)已经排序,是否真的需要(重新)排序单独的数组?
    • @DavidBerry 不错。我没有注意到最初的排序。你是对的,不需要对两个数组进行额外的排序,因为fetchedEvent 已经按开始日期排序。
    • 我想我也会完全消除 allDayersdateIntervals 并通过 fetchedEvents 转储到适当的桶中,但这只是挑剔。
    • 优美的语法。它的作用就像红酒和法国奶酪。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-23
    • 1970-01-01
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 2022-01-12
    • 2017-04-06
    相关资源
    最近更新 更多