起動時に現在時刻のセクションを表示する
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...
文字化けるのか!