【问题标题】:Sorting most descending date at top TableView在 TableView 顶部对降序的日期进行排序
【发布时间】:2017-04-06 06:24:29
【问题描述】:

情况

我有一个表格视图,其中存储在单元格中的预定本地通知,包含标题、日期、UUID 和心情。他们从用户选择的那一天开始每周重复一次,并且工作得很好。我已经成功地对单元格进行了排序,以便通过refreshList() 中的这行代码,最降序(最快)的通知位于表格视图的顶部:

dqItems.sort(by: {$0.date < $1.date})

问题

但是,当通知已被触发并过期时,将通过 if (dqItem.isOverdue) 函数将其日期添加 7 天。这有效 - 7 天被添加到日期。但是 tableview 不会重新排序单元格 - 已经重新安排了 7 天的通知单元格仍然在顶部!尽管有其他通知安排了更多的降序日期。 (以图片为例)

这非常令人沮丧,我无法找到解决方案。这是来自Table View Controller 文件的sn-p。

//Outlets
var dqItems: [DQItem] = []
var MoodString = String()

 override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    refreshList()
}

func refreshList() {

    dqItems = DQList.sharedInstance.allItems()

        dqItems.sort(by: {$0.date < $1.date})

    tableView.reloadData()
}

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return dqItems.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "dqCell", for: indexPath) // retrieve the prototype cell (subtitle style)
    var dqItem = dqItems[(indexPath as NSIndexPath).row] as DQItem
    cell.textLabel?.text = dqItem.title as String!

    if (dqItem.isOverdue)
    { // the current time is later than the to-do item's date

        let newDate = Calendar.current.date(byAdding: .day, value: 7, to: dqItem.date)!
        dqItem.date = newDate
        dateFormatter.dateFormat = "EEEE's' 'at' HH:mm"
        print("newdate", newDate) //seven days is added!
        print("dqItem.d", dqItem.date) //same here

       viewDidAppear(true) //reload the view to re-sort the cells??? = not working

    }

    cell.detailTextLabel?.text = dateFormatter.string(from: dqItem.date as Date)

    return cell
}//End of cellforrowatindexPath

结构体所在的 DQItem。

 import UIKit

 struct DQItem {

  var title: String
  var date: Date
  var UUID: String
  var mood: String

init(date: Date, title: String, UUID: String, mood: String) { 

    self.date = date
    self.title = title
    self.UUID = UUID
    self.mood = mood

}

 //Overdue function
 var isOverdue: Bool {

     return (Date().compare(self.date) == .orderedDescending) // date is earlier than current date
}



}

感谢所有尝试解决这个愚蠢问题的帮助!

【问题讨论】:

    标签: swift xcode uitableview nsdate cell


    【解决方案1】:

    不要打电话给viewDidAppear。该方法应该只被UIKit 调用。只需调用您自己的刷新代码即可。

    (即使调用视图状态方法是一个好主意,你也会调用错误的方法,因为你实现了viewWillAppear 来进行初始刷新。)

    编辑: 对于在更新表格时如何更改表格顺序的问题,您需要等到当前更新完成。一种方法是将下一个重新加载请求提交到主队列。由于主队列是串行的,这会将其延迟到当前工作完成。

    尝试将重新排序的表移动到自己的方法中...

    func orderTable() {
        dqItems.sort(by: {$0.date < $1.date})
        tableView.reloadData()
    }
    

    ...然后通过 GCD 调用它,而不是调用视图生命周期方法。

    DispatchQueue.main.async {
        orderTable()
    }
    

    这是简单的版本。如果您想提高效率,可以考虑确保每次重新加载时只调用一次 orderTable

    【讨论】:

    • 尝试将 dqItems.sort(by: {$0.date
    • 你也打电话给reloadData吗?
    • 是的,但是它会创建一个函数循环然后...这证实了代码无法使用新的 7 天 + dqItem.Date 并替换已经触发的旧的事实。有没有办法将过期的Table View Cell 发送到Table View 的底部?它也可以解决我的问题。 @philipMills
    • 当然……对不起!一种方法可能是将排序和重新加载放入一个块中并将其异步分派到主队列。这应该可以解决循环问题。
    • 您介意通过再次回答问题向我展示您的意思吗?我是编程新手,非常感谢您的帮助:) @philipMills
    猜你喜欢
    • 1970-01-01
    • 2014-06-07
    • 1970-01-01
    • 2015-09-28
    • 2013-01-10
    • 2014-12-13
    • 2016-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多