2016-11-22 4 views
0

で最も降順の日付を並べ替え状況トップテーブルビュー

私はタイトル、日付、UUIDと気分を含む、細胞に保存されている予定のローカル通知とテーブルビューを持っています。彼らは、ユーザーが選択した日から毎週繰り返し、完璧に動作します。

しかし、

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

問題:最も下降(最も早い)通知refreshList()にコード行を介してテーブルビューの一番上になるように、私は正常細胞をソートしました通知が発効して延滞している場合は、if (dqItem.isOverdue)機能を介して7日間が日付に追加されています。これは動作します - 7日が日付に追加されます。しかし、tableviewは、セルを再ソートしません - 7日で再スケジュールされている通知セルはまだ一番上にあります!実際、他の通知が降順にスケジュールされているにもかかわらず、 (画像などを参照)

これは非常にイライラしており、私は解決策を見つけることができません。ここにTable View Controllerファイルのスニペットがあります。

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



} 

このばかげた問題を解決しようとすると助けてください!

Example: "Today" comes after "Next Thursday" despite the fact it's more descending

答えて

1

viewDidAppearを呼び出さないでください。このメソッドは、UIKitによってのみ呼び出されるはずです。代わりに独自のリフレッシュコードを呼び出してください。

(あなたが最初のリフレッシュを行うためにviewWillAppearを実装するので、ビューステートのメソッドを呼び出すことは良いアイデアだったとしても、あなたは間違ったものを呼び出すことになる。)

EDIT: あなたのテーブルを変更する方法の問題のためにテーブルが更新されている間に注文するには、現在の更新が完了するまで待つ必要があります。これを行う1つの方法は、次のリロード要求をメインキューにサブミットすることです。メインキューはシリアルであるため、現在の作業が終了するまで待機します。

は、代わりにビューのライフサイクルメソッドを呼び出すのGCDを経由して、それを呼び出す...

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

...独自のメソッドに並べ替えテーブルを移動してみてください。

DispatchQueue.main.async { 
    orderTable() 
} 

これは単純なバージョンです。より効率的にするには、orderTableコールがリロードごとに1回だけ発生することを確認する方法を調べることができます。

+0

viewWillAppearではなくdqItems.sort(by:{$ 0.date <$ 1.date})を関数に追加しようとしました。変更はありません。問題の明確な説明については、質問の更新をご覧ください。ありがとう@philipMills – Mate

+0

'reloadData'も呼びますか? –

+0

はい、それは関数のループを作成します。これは、コードが新しい7日間+ 'dqItem.Date'を使用して、既に起動した古いものを置き換えないことを確認します。期限切れの 'Table View Cell'を' Table View'の一番下に送る方法はありますか?それも私の問題を解決するだろう。 @philipMills – Mate