実現したいこと
PageViewControllerを使って3ページで構成されているAppを実装しております。
その2ページ目から3ページ目に初めてスワイプして遷移したときと全く同じ挙動を毎回2ページ目から3ページ目に遷移するときはさせたいです。
発生している問題
- CalendarViewController
- TodayViewController
- RecordViewController
ページは上の3ページで構成されており、ページ2でデータの変更&保存ができます。3ページ目はその保存されたデータを元にチャートを表示するようにしております。
初期表示が2ページ目になっており、初めて2ページ目から3ページ目にいくときは2ページ目で変更や保存したデータが適切にチャートで表示されます。
ですがその後スワイプでページ2に戻ってから、データを更新してページ3にいくとその結果が反映されず、先ほど表示されたチャートがそのまま表示されてしまいます。
どのようにすれば毎回2ページ目から3ページ目に行くときは初めて2ページ目から3ページ目にいくときの挙動にできるでしょうか?
import UIKit class PageViewController: UIPageViewController { override func viewDidLoad() { super.viewDidLoad() self.setViewControllers([getTodayPage()], direction: .forward, animated: true, completion: nil) self.dataSource = self // self.delegate = self } func getTodayPage() -> TodayViewController { let todayView = storyboard!.instantiateViewController(withIdentifier: "todayViewIdentifier") as! TodayViewController todayView.selectedDate = selectedDate return todayView } func getCalendarPage() -> CalendarViewController { return storyboard!.instantiateViewController(withIdentifier: "calendarView") as! CalendarViewController } func getRecordPage() -> RecordViewController { return storyboard!.instantiateViewController(withIdentifier: "recordView") as! RecordViewController } } extension PageViewController : UIPageViewControllerDataSource { func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { if viewController.isKind(of: RecordViewController.self) { return getTodayPage() } else if viewController.isKind(of: TodayViewController.self) { return getCalendarPage() }else{ return nil } } func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { if viewController.isKind(of: CalendarViewController.self) { return getTodayPage() } else if viewController.isKind(of: TodayViewController.self) { return getRecordPage() }else{ return nil } } } //extension PageViewController: UIPageViewControllerDelegate { // func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { // if completed { // guard let recordViewController = pageViewController.viewControllers?.first as? RecordViewController else { // return // } // // // Ver 1 (recordViewControllerをviewDidLoad()) // recordViewController.viewDidLoad() // // // Ver 2 (recordViewControllerのscrollView内のsubviews(こちらに削除する複数のチャートが含まれています)を削除してからviewDidLoad()) // let subviews = recordViewController.scrollView.subviews // // for subview in subviews { // subview.removeFromSuperview() // } // // recordViewController.viewDidLoad() // // // } // } //}
試したこと
teratail上で前回ご質問させていただきまして、上のソースコードでコメントアウトしているUIPageViewControllerDelegateメソッドを使うことでスワイプでのページ遷移ごとに毎回データを更新することはできるようになりました。
ただViewの表示が思ったようにはできませんでした。
Ver1, Ver2とそれぞれ試してみましたが
Ver1 → チャートの上にもう1度同じチャートが上書きされてしまうだけ
Ver2 → 上書きはされなくなり、チャートは表示されるがその表示が適切ではなくデータにそぐわないもので、View全体のLayoutも崩れてしまい、カクカクした感じがあり、チャート描画のアニメーションもおかしい
など様々な問題が起き理想の挙動が実現できなかったためもっとシンプルに考えて
初めて2ページ目から3ページ目に行くときの挙動は完璧なので毎回2ページ目から3ページ目にいくときはそのときと同じ挙動にすれば全てが解決するのではないかと考えました。
ただその方法がわかりかねております。それさえわかればその方法をDelegateメソッドに書くことで解決できるのではないかと考えております。
皆様のお力添えいただけますと幸いです。
何卒よろしくお願いいたします。
補足情報(言語/FW/ツール等のバージョンなど)
Swift 5.0.1
Xcode 10.2.1
情報の追加・修正依頼を受けての追記
RecordViewControllerのチャート生成部分の記述は以下のようになっております。
RecordViewController
1//ChartViewを生成 2let rect = CGRect.init(x:((self.view.bounds.width-self.view.bounds.width * 0.9)/2), y: 175, width: self.view.bounds.width * 0.9, height: 500) 3let chartView = ChartView(frame: rect) 4 5//表示 6self.scrollView.addSubview(chartView) 7 8//chartViewの位置を指定 9scrollView.addSubview(chartView) 10chartView.translatesAutoresizingMaskIntoConstraints = false 11chartView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true 12chartView.topAnchor.constraint(equalTo: dailyLabel.bottomAnchor, constant: 20).isActive = true 13chartView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 40).isActive = true 14chartView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: 40).isActive = true 15 16//Realmからチャート描画のためのデータを取得 17ChartView.createData { recordDataArray in 18 19 ChartView.lastSevenRecords = recordDataArray 20 21 //期間中のスコア全て配列に格納 22 var scoreArray = [Int16]() 23 for recordData in recordDataArray { 24 25 scoreArray.append(recordData.score) 26 27 } 28 29 //期間中の最高スコアを取得 30 let maxScore = Int(scoreArray.max()!) 31 32 if maxScore == 0 { 33 34 ChartView.maxValue = 10 * 100 35 36 } else { 37 38 //最高スコアを10の倍数に切り上げたものをChartViewのmaxValueに代入 39 ChartView.maxValue = self.getTenTimesNumber(num: maxScore, base: 10) * 100 //この100はmaxValueの値をyAxisHeightより大きくするために必要なもの 40 41 } 42 43 let node = ChartView.createChart() 44 //取得したデータをチャート描画するために反映させアニメーション 45 chartView.updateShape(node: node) 46 chartView.contentMode = .scaleAspectFit 47 ChartView.playAnimations() 48 49}
回答1件
あなたの回答
tips
プレビュー