【问题标题】:swift 3 numberofrowsinsection runs before viewwillappear fetches remindersswift 3 numberofrowsinsection 在 vi​​ewwillappear 获取提醒之前运行
【发布时间】:2016-11-22 04:09:37
【问题描述】:

想在检索提醒方面寻求帮助。似乎 numberOfRowsInSection 甚至在 eventStore.fetchReminders 完成之前就被调用了。这是我的代码:

override func viewWillAppear(_ animated: Bool) {
    print("****viewWillAppear")
    super.viewWillAppear(true)
    self.eventStore = EKEventStore()
    self.reminders = [EKReminder]()
    //Added to initialize
    self.reminders.removeAll()
    self.eventStore!.requestAccess(to: EKEntityType.reminder, completion:
        {(granted, error) in
            if granted
            {
                let predicate = self.eventStore.predicateForReminders(in: nil)
                self.eventStore.fetchReminders(matching: predicate, completion: { (reminders: [EKReminder]?) -> Void in
                    self.reminders = reminders
                    DispatchQueue.main.async() {
                        //Added 
                        self.reminders = reminders
                        self.tableView.reloadData()
                    }
                })

            }
            else 
            {
                print("The app is not permitted to access reminders, make sure to grant permission in the settings and try again")
            }
    })

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

    print("*****numberOfRowsInSection")
    print("numberOfRowsInSection reminders \(self.reminders.count)")
    return self.reminders.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    print("****titleForHeaderInSection")
    print("titleForHeaderInSection reminders \(self.reminders.count)")
    return "test"
}

我尝试将其放入 viewDidLoad 但同样的事情发生了,numberofRowsInSection 中的 self.reminders.count 返回 0。我还尝试在 requestAccess 的外部调用 fetchReminders(因为我认为 requestAccess 没有触发),但我最终得到一样的东西。有什么我做错了吗? 非常感谢任何建议!

谢谢!

【问题讨论】:

  • 您可以尝试在您的 viewWillAppear 中添加 super.viewWillAppear() 吗?您还应该在 viewDidLoad() 中调用以下内容:self.eventStore!.requestAccess(to: EKEntityType.reminder, completion:
  • 嗨,迈克尔,谢谢!我添加了 super.viewWillAppear。我还在 viewDidLoad 中添加了 requestAccess。我得到了相同的结果:(
  • 至少你在这里得到了更好的代码。即使它没有解决您的问题;)很高兴看到您可以解决它。

标签: swift swift3 reminders ekeventstore


【解决方案1】:

这是正常的。 UITableViewController 尝试在显示视图控制器时显示表视图的内容。您应该在viewDidLoad 的开头使用一个空数组初始化self.reminders,这样表格视图最初不会显示任何结果。

然后,一旦您完成对事件存储的访问,将调用您重置 self.reminders 并重新加载表格视图的代码。

您应该进行的一项重要更改是在DispatchQueue.main.async() 块内设置self.reminders。这可确保在重新加载表之前而不是在手之前更新数据源。换句话说,将您的代码更新为:

self.eventStore.fetchReminders(matching: predicate, completion: { (reminders: [EKReminder]?) -> Void in
    DispatchQueue.main.async() {
        self.reminders = reminders
        self.tableView.reloadData()
    }
})

要考虑的另一个更改是最初将self.reminders 设置为nil,并让您的表格视图数据源方法将此视为一个信号,以显示显示“正在加载”(或类似内容)的一行。否则,您的用户可能会想知道为什么他们会在很短的一段时间内盯着几乎是空白的屏幕。

【讨论】:

  • 谢谢麦迪! “在 dispatchqeueue.main.async() 块中设置 self.reminders”是什么意思?
  • 顺便说一句抱歉,我忘了说,我是 swift 新手。根据我的发现,viewWillAppear 触发,然后当它看到“self.eventStore!.requestAccess(to:EKEntityType.reminder,completion:”)然后它直接跳转到查看 numberOfSections 函数。经过几个循环(2-3)然后它再次返回并运行 fetchReminders 代码。
  • 查看我更新的答案,显示我对 async 块的意思。
  • 嗨,maddy,我已经更新了上面的代码。似乎它在做同样的事情。这是我的日志: *****View Did Load... BEFORE PredicateForReminders.... AFTER PredicateForReminders.... ****viewWillAppear ****numberOfSections Reminders count 0 ****titleForHeaderInSection titleForHeaderInSection 提醒 0
  • 您是否使用过调试器并验证了对fetchReminders 的调用实际上正在被调用?你确定正在调用完成块吗?结果中是否有提醒?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-28
  • 1970-01-01
  • 1970-01-01
  • 2021-05-16
  • 1970-01-01
  • 2011-08-20
相关资源
最近更新 更多