从完成块获取行数时构建表视图

时间:2015-10-26 15:56:52

标签: ios xcode swift swift2 ios9

我正在尝试在swift 2中检索日历事件,我无法解决这个问题:构建表视图我需要知道单元格的数量,我可以从这样的方法中获取(为了简单数组是String):

func fetchCalendarEvents () -> [String] {

    var arrayW = [String]()

    let eventStore : EKEventStore = EKEventStore()


    eventStore.requestAccessToEntityType(EKEntityType.Event, completion: {
        granted, error in
        if (granted) && (error == nil) {
            print("access granted: \(granted)")

            //do stuff...
        }
        else {
            print("error: access not granted  \(error)")

        }
    })
    return arrayW
}

我在viewDidLoad中调用此方法,并将数组保存到 var eventArray 。立即调用以下方法:

 override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return eventArray.count
}

问题是此时fetchCalendarEvents的完成块不完整,因此返回0(而日历中有事件)。

我的问题:如何处理从我从方法获得的数组构建表视图,具有完成块,并且需要一些时间才能完成?

4 个答案:

答案 0 :(得分:2)

在日历完成功能块中添加aBlockSelf.tableView.reloadData(),以使用提取的数据重新加载表格。

此处aBlockSelfself的弱引用,因为它被传递给一个块。

编辑:发布OP评论 - 试试这个:

weak var aBlockSelf = self

答案 1 :(得分:1)

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if (eventArray.count == 0) { //or unwrap value, depends on your code
        return 0 // or 1, if you want add a 'Loading' cell
    } else {
        return eventArray.count
    }    
}

而且,当你得到eventArray时,只需用

重新加载表
//without animation
tableView.reloadData()
//or with, but it can get little tricky
tableView.insertRowsAtIndexPaths(indexArray, withRowAnimation:UITableViewRowAnimationRight];

答案 2 :(得分:0)

制作2个单元格类型。一个用于事件,一个用于说“正在加载...”。正在进行的阻止只显示1个“正在加载...”的单元格。当事件将检索时隐藏此单元格并使用事件重新加载表。
欢呼声。

答案 3 :(得分:0)

好的,所有人似乎都回答得相对正确,但并不完全符合直线的方式。对我来说有用的是,我只需要在for循环之后重新加载表视图,而不是返回数组:

func fetchCalendarEvents () {

    let eventStore : EKEventStore = EKEventStore()

    eventStore.requestAccessToEntityType(EKEntityType.Event, completion: {
        granted, error in
        if (granted) && (error == nil) {
            print("access granted: \(granted)")
            let startDate=NSDate().dateByAddingTimeInterval(-60*60*24)
            let endDate=NSDate().dateByAddingTimeInterval(60*60*24*3)
            let predicate2 = eventStore.predicateForEventsWithStartDate(startDate, endDate: endDate, calendars: nil)

            print("startDate:\(startDate) endDate:\(endDate)")
            let events = eventStore.eventsMatchingPredicate(predicate2) as [EKEvent]!

            if events != nil {

                var arrayOfEvents = [CalendarEventObject]()

                for event in events {
                    var eventObject: CalendarEventObject

                    //  (ಠ_ಠ)  HARDCODEDE
                    eventObject = CalendarEventObject(id: 0, title: event.title, location: event.location!, notes: event.notes!, startTime: event.startDate, endTime: event.endDate, host: "host", origin: "origin", numbers: ["0611111111", "0611111112"], passcodes: ["123456", "123457"], hostcodes: ["123458", "123459"], selectedNumber: "0611111113", selectedPasscode: "123457", selectedHostcode: "123459", scheduled: true, parsed: false, update: true, preferences: [], eventUrl: "www.youtube.com", attendees: [])

                    arrayOfEvents.append(eventObject)

                }

                self.eventArray = arrayOfEvents

                //reload data after getting the array
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    self.tableView.reloadData()
                })
            }
        }
        else {
            print("error: access not granted  \(error)")

        }
    })
}