前提・実現したいこと
いつも大変お世話になっております!
TableViewにsectionで日付を昇順で並べています。
起動したその日が2020/8/30とした場合、その日付のsectionがTableViewの一番上に来るようにします。
その日付が配列に存在するときは問題なく機能しましたが、配列に存在しない場合、次の予定が一番上に来るように実装したいのです。
発生している問題・エラーメッセージ
下記のコードのように、もし今日の日付が配列の中の日付に一致しなかった場合は、
filterを使って本日以降の日付を新しく配列を作り入れます。
その始めにくる日付の配列番号が想定する日付になるので番号を取り出せたらと思うのですが、
記載したスクショの通り フィルター後の予定日時配列 が一度にfilteringされない為かnilになってしまい、
番号が上手く取り出せません。
もっと賢いやり方があるのかもしれませんが、どなたかご教授頂ければ大変たすかります。
何卒よろしくお願いいたします。
該当のソースコード
fileprivate let gregorian: Calendar = Calendar(identifier: .gregorian) fileprivate lazy var dateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.locale = Locale(identifier: "en_US_POSIX") formatter.dateFormat = "yyyy-MM-dd" return formatter }() var dateArray = [String]() for num in 0..<editDic.count{ dateArray.append(editDic[num].date) } /****重複を消す****/ let duplicateDAOS:NSOrderedSet = NSOrderedSet(array: dateArray) let stringArray = duplicateDAOS.array as! [String] let scheduleArray = stringArray.sorted { ( lDate, rDate) -> Bool in return lDate < rDate } print("予定日時配列: ",scheduleArray) let date = Date() let today = dateFormatter.string(from: date) print("今日の日付: ",today) let section = scheduleArray.firstIndex(of: today) if section != nil{ let indexPath = IndexPath(row: 0, section: section ?? 0) DispatchQueue.main.async { self.tableView.scrollToRow(at: indexPath, at: .top, animated: false) } }else if section == nil{ let filteredScheduleArray = scheduleArray.filter({ element in element > today }) print("フィルター後の予定日時配列: ",filteredScheduleArray) //let nextScheDate = filteredScheduleArray[0] //let section = filteredScheduleArray.firstIndex(of: nextScheDate) let indexPath = IndexPath(row: 0, section: section ?? 0) DispatchQueue.main.async { self.tableView.scrollToRow(at: indexPath, at: .top, animated: false) } } tableView.reloadData() }
補足情報(FW/ツールのバージョンなど)
//let nextScheDate = filteredScheduleArray[0]
//let section = filteredScheduleArray.firstIndex(of: nextScheDate)
これら2行をコメントアウトすると以下の写真のように順番に配列に足されていくことが確認できますが、一番始めは[]からになってます。
例の2行をコメントアウトしなかった場合は落ちてしまいます。
全て配列に入りきってから配列番号を取得しようと試みるのですが、呼び出しの場所を変えても状態は変わらず。
改めてご教授頂ければと思います。よろしくお願いします。
修正コードはこちら
/****重複を消す****/ let duplicateDAOS:NSOrderedSet = NSOrderedSet(array: dateArray) let stringArray = duplicateDAOS.array as! [String] let scheduleArray = stringArray.sorted { ( lDate, rDate) -> Bool in return lDate < rDate } print("予定日時配列: ",scheduleArray) let date = Date() let today = dateFormatter.string(from: date) print("今日の日付: ",today) let section = scheduleArray.firstIndex(of: today) if section != nil{ let indexPath = IndexPath(row: 0, section: section ?? 0) DispatchQueue.main.async { self.tableView.scrollToRow(at: indexPath, at: .top, animated: false) } }else if section == nil{ let filteredScheduleArray1 = scheduleArray.filter({ element in element > today }) print("配列、次の予定日時が始めに来る: ",filteredScheduleArray1) if filteredScheduleArray1.isEmpty == false{ let nextSection = filteredScheduleArray1.startIndex + 1 let indexPath = IndexPath(row: 0, section: nextSection) DispatchQueue.main.async { self.tableView.scrollToRow(at: indexPath, at: .top, animated: false) } }else if filteredScheduleArray1.isEmpty == true{ let filteredScheduleArray2 = scheduleArray.filter({ element in element < today }) let preSection = filteredScheduleArray2.endIndex + 1 print("配列、消化した日程最終日が最後に来る: ",filteredScheduleArray2) let indexPath = IndexPath(row: 0, section: preSection) DispatchQueue.main.async { self.tableView.scrollToRow(at: indexPath, at: .top, animated: false) } } } tableView.reloadData() }
********************************************************
解決致しました!
TsukubaDepotさんのリンクを参照しました。
https://teratail.com/questions/288703
コード記載は****マークで囲ってあります。
解決したコード
var schedule = [Date: [schedules]]() var dateOrder = [Date]() var editDic1 = [schedules]() var editDic2 = [schedules]() var editDicAll = [schedules]() var editDic = [schedules]() func combineInfosToSingleArray(editDic:[schedules]){ self.editDic.removeAll() self.editDicAll = editDic1 + editDic2 editDic = self.editDicAll.sorted { ( ldate, rdate) -> Bool in return ldate.date < rdate.date } ****ここにcompletionを入れて、firebaseから読み込んだ2つの違うデータを 一つの配列に入れてから、次の処理へ移行するようにしました*** setGrouping(editDic: editDic, completion: { self.displaySectionOnTop(editDic: self.editDic) }) ************************************************* tableView.reloadData() } func displaySectionOnTop(editDic:[schedules]){ var dateArray = [String]() for num in 0..<editDic.count{ dateArray.append(editDic[num].date) } /****重複を消す****/ let duplicateDAOS:NSOrderedSet = NSOrderedSet(array: dateArray) let stringArray = duplicateDAOS.array as! [String] let scheduleArray = stringArray.sorted { ( lDate, rDate) -> Bool in return lDate < rDate } print("スケジュール配列: ",scheduleArray) let date = Date() let today = dateFormatter.string(from: date) if let index = scheduleArray.firstIndex(of: today){ let indexPath = IndexPath(row: 0, section: index) DispatchQueue.main.async { self.tableView.scrollToRow(at: indexPath, at: .top, animated: false) } }else{ print("本日 ((today)) 予定はありませんでした。") let filteredScheduleArray = scheduleArray.filter({ element in element > today }) if let nextScheDate = filteredScheduleArray.first{ let index = filteredScheduleArray.firstIndex(of: nextScheDate) let getNextSection = scheduleArray.count - filteredScheduleArray.count let section = getNextSection + index! let indexPath = IndexPath(row: 0, section: section) DispatchQueue.main.async { self.tableView.scrollToRow(at: indexPath, at: .top, animated: false) print("次の直近の予定日は (nextScheDate) で、要素番号は (section) です。") } }else{ let filteredScheduleArray = scheduleArray.filter({ element in element < today }) if let lastDate = filteredScheduleArray.last{ let section = filteredScheduleArray.firstIndex(of: lastDate) let indexPath = IndexPath(row:0,section: section!) DispatchQueue.main.async { self.tableView.scrollToRow(at: indexPath, at: .top, animated: false) print("直近の予定はありませんでした。") print("前回の予定は (lastDate) で、要素番号は (section!) です。") } }else{ print("登録されている予定は 0 件です") } } } tableView.reloadData() } ****こちらの関数で@escaping()->()と,下記にDispatchQueue.main.async{completion()}を追加しました**** func setGrouping(editDic:[schedules], completion: @escaping()->()){ schedule = Dictionary(grouping: editDic){ project -> Date in let date = dateFormatter.date(from: project.date) return date ?? Date() } .reduce(into:[Date:[schedules]]()) { dic, tuple in dic[tuple.key] = tuple.value.sorted { $0.date < $1.date} } dateOrder = Array(schedules.keys).sorted{ $0 < $1} ******こちら******** DispatchQueue.main.async { completion() } ****************** }
回答1件
あなたの回答
tips
プレビュー