huinme/YAPCViewer

起動時に現在時刻のセクションを表示する

Closed this issue · 9 comments

こんな感じかなと思ってるけど、viewDidLoadの[self _fetchTalksForDateString:self.eventDays[0]];時点で0を渡すのではなく日にちの変更も必要だから一旦issueだけ切る

diff --git a/YAPCViewer/Classes/ViewControlleres/YVTalkListViewController.m b/YAPCViewer/Classes/ViewControlleres/YVTalkListViewController.m
index 5e25b18..0704445 100644
--- a/YAPCViewer/Classes/ViewControlleres/YVTalkListViewController.m
+++ b/YAPCViewer/Classes/ViewControlleres/YVTalkListViewController.m
@@ -87,6 +87,7 @@ static NSString *const kYVTalkListThirdDateString   = @"2013-09-21";

 - (void)viewWillAppear:(BOOL)animated
 {
+    [self _scrollToCurrentSection];
     [super viewWillAppear:animated];
 }

@@ -185,6 +186,25 @@ static NSString *const kYVTalkListThirdDateString   = @"2013-09-21";
     return items;
 }

+- (void)_scrollToCurrentSection
+{
+    NSDateComponents *cal = [[NSCalendar currentCalendar] components:NSHourCalendarUnit | NSMinuteCalendarUnit
+                                                           fromDate:[NSDate date]];
+    __block NSString *now = [NSString stringWithFormat:@"%02d:%02d", cal.hour, cal.minute];
+    __block NSUInteger targetSection;
+    [self.frController.sections enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+        if ([now compare:(NSString *)[obj name]] < 0) {
+            *stop = YES;
+            return;
+        }
+
+        targetSection = idx;
+    }];
+
+    NSIndexPath* indexPath = [NSIndexPath indexPathForRow:0 inSection:targetSection];
+    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
+}
+

[self _fetchTalksForDateString:self.eventDays[0]]; も変更して初期tableの表示変更。

diff --git a/YAPCViewer/Classes/ViewControlleres/YVTalkListViewController.m b/YAPCViewer/Classes/ViewControlleres/YVTalkListViewController.m
index 5e25b18..260b786 100644
--- a/YAPCViewer/Classes/ViewControlleres/YVTalkListViewController.m
+++ b/YAPCViewer/Classes/ViewControlleres/YVTalkListViewController.m
@@ -82,11 +82,12 @@ static NSString *const kYVTalkListThirdDateString   = @"2013-09-21";
     self.searchController.searchResultsDataSource = self;
     self.searchController.searchResultsDelegate = self;

-    [self _fetchTalksForDateString:self.eventDays[0]];
+    [self _fetchTalksForDateString:self.eventDays[[self _daysIndexByCurrentDate]]];
 }

 - (void)viewWillAppear:(BOOL)animated
 {
+    [self _scrollToCurrentSection];
     [super viewWillAppear:animated];
 }

@@ -185,6 +186,40 @@ static NSString *const kYVTalkListThirdDateString   = @"2013-09-21";
     return items;
 }

+- (NSUInteger)_daysIndexByCurrentDate
+{
+    NSDateComponents *cal = [[NSCalendar currentCalendar] components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
+                                                              fromDate:[NSDate date]];
+    NSString *now = [NSString stringWithFormat:@"%04d-%02d-%02d", cal.year, cal.month, cal.day];
+
+    if([now isEqualToString:kYVTalkListSecondDateString]){
+        return 1;
+    }else if([now isEqualToString:kYVTalkListThirdDateString]){
+        return 2;
+    }else{
+        return 0;
+    }
+}
+
+- (void)_scrollToCurrentSection
+{
+    NSDateComponents *cal = [[NSCalendar currentCalendar] components:NSHourCalendarUnit | NSMinuteCalendarUnit
+                                                           fromDate:[NSDate date]];
+    __block NSString *now = [NSString stringWithFormat:@"%02d:%02d", cal.hour, cal.minute];
+    __block NSUInteger targetSection;
+    [self.frController.sections enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+        if ([now compare:(NSString *)[obj name]] < 0) {
+            *stop = YES;
+            return;
+        }
+
+        targetSection = idx;
+    }];
+
+    NSIndexPath* indexPath = [NSIndexPath indexPathForRow:0 inSection:targetSection];
+    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 #pragma mark - YVEventDayViewDelegate
 ////////////////////////////////////////////////////////////////////////////////

あとはYVEventDayView.mの以下の辺を外から触れるようにするとかしないと日付の表示が変わらないからダメそう。

    self.currentEventDaysIndex = 0;

    [self _displayDateForCurrentIndex];

    [self _updateButtonStateForIndex:self.currentEventDaysIndex];

今日の夜やる.

  • 会期中以外は発動しない.
  • インストール後初回起動時はデータを取得する前なので、発動しない.

という制限付きだけど2回目以降のゼロ起動で一応動く.

あれ?コード見た感じ、

インストール後初回起動時はデータを取得する前なので、発動しない.

NSInteger indexToGo = [scroller eventIndexForCurrentDate];があるので、インストール後初回起動時でも発動するのではないの?

viewDidLoad内にあるYVEventSrollerは3日程のどこを表示させるかを決めてるだけですね.
その後の- (void)_scrollToCurrentTalk内で移動を行うんですが、
インストール後の初回起動時は、データがないので移動先がなくて何も起きません.

だいぶ流れを追いにくいコードになってて後悔してるんですが、

- (void)viewDidLoad
{
    /* ... */

    [self.eventDayView setEventDayIndex:indexOfDate]; //  A) 日付が変わる.
    [self _scrollToCurrentTalk]; // B) スクロールの呼び出し
}

// →日付が変わった時のdelegateで呼ばれる.
- (void)eventDayView:(YVEventDayView *)eventDayView
       dayDidChanged:(NSString *)dayString
{
    [self _fetchTalksForDateString:dayString]; // C) データの取得
}

- (void)_fetchTalksForDateString:(NSString *)dateString
{
    if(![self.frController performFetch:&fetchError]){
        YVLog(@"FETCH ERROR : %@", fetchError);
    }

    [self.tableView reloadData];  // D) テーブルの更新 

    [[YVTalks new] fetchTalksForDate:dateString
                         withHandler:
     ^(NSDictionary *dataDict, NSError *error) {
           // E) バックグラウンドでデータの保存(非同期)
     }];
}

// データの保存完了後にテーブルの更新
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView reloadData];   // F) テーブルの更新 
}

- (void)_scrollToCurrentTalk
{
    // G) セクションの移動
    [self.tableView scrollToRowAtIndexPath:indexPath
                          atScrollPosition:UITableViewScrollPositionTop
                                  animated:YES];
}

非同期処理も考慮した上で、処理の順番的には

A) → C) → D) → G) → E) → F)

となるのですが、
初回起動時には D) ではデータがないのでスクロール失敗.
2回目以降は D) 時点でデータがあるので、その後の G) でスクロールできる.
というわけです.

(そもそもYVEventScrollerというクラス名が非常に良くないですね)

あー!そうだった。_fetchTalksForDateStringのデータ保存は非同期だった。
やっぱり現時点の初回データをアプリに突っ込んどくのが良いですね。

んー初期データの埋め込みは実は以外と大変だったり...

oh...sqlite�$B%U%!%$%k$r�(BDocument�$B$KCV$/$N4JC1$@$H;W$C$F$?�(B...

文字化けるのか!