UIPageViewControllerに非常に興味深い問題があります。
私のプロジェクトは、サンプルのページベースのアプリケーションテンプレートと非常によく似ています。時々(ただし、ある程度再現可能)、特定のパンジェスチャがに呼び出され-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
ます。
次のページのビューコントローラを返しますが、ページめくりアニメーションが実行されず、デリゲートメソッドが呼び出されません。
これがのコードですviewControllerAfterViewController
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
PageDisplayViewController *vc = (PageDisplayViewController *)viewController;
NSUInteger index = [self.pageFetchController.fetchedObjects indexOfObject:vc.page];
if(index == (self.pageFetchController.fetchedObjects.count - 1)) return nil;
return [self getViewControllerForIndex:(++index)];
}
これがgetViewControllerForIndex:
-(PageDisplayViewController *)getViewControllerForIndex:(NSUInteger)index
{
PageDisplayViewController *newVC = [self.storyboard instantiateViewControllerWithIdentifier:@"PageDisplayController"];
newVC.page = [self.pageFetchController.fetchedObjects objectAtIndex:(index)];
newVC.view.frame = CGRectMake(0, 0, 1024, 604);
NSLog(@"%i", index);
if(index == 0)
{
//We're moving to the first, animate the back button to be hidden.
[UIView animateWithDuration:0.5 animations:^
{
self.backButton.alpha = 0.f;
} completion:^(BOOL finished){
self.backButton.hidden = YES;
}];
}
else if(index == (self.pageFetchController.fetchedObjects.count - 1))
{
[UIView animateWithDuration:0.5 animations:^{
self.nextButton.alpha = 0.f;
} completion:^(BOOL finished){
self.nextButton.hidden = YES;
}];
}
else
{
BOOL eitherIsHidden = self.nextButton.hidden || self.backButton.hidden;
if(eitherIsHidden)
{
[UIView animateWithDuration:0.5 animations:^{
if(self.nextButton.hidden)
{
self.nextButton.hidden = NO;
self.nextButton.alpha = 1.f;
}
if(self.backButton.hidden)
{
self.backButton.hidden = NO;
self.backButton.alpha = 1.f;
}
}];
}
}
return newVC;
}
基本的には、View Controllerを作成し、そのデータオブジェクトを設定してから、インデックスに応じて[次へ]/[戻る]ボタンをフェードアウトします。
デリゲート方式
-(void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
PageDisplayViewController *vc = [previousViewControllers lastObject];
NSUInteger index = [self.pageFetchController.fetchedObjects indexOfObject:vc.page];
if (!completed)
{
[self.pagePreviewView setCurrentIndex:index];
NSLog(@"Animation Did not complete, reverting pagepreview");
}
else
{
PageDisplayViewController *curr = [pageViewController.viewControllers lastObject];
NSUInteger i = [self.pageFetchController.fetchedObjects indexOfObject:curr.page];
[self.pagePreviewView setCurrentIndex:i];
NSLog(@"Animation compeleted, updating pagepreview. Index: %u", i);
}
}
この問題に気付いたのは、ランダムに戻るボタンが画面に再表示されるためです。そこにいくつかのNSLog()
ステートメントを入れた後、dataSourceメソッドがインデックス1に対して呼び出されることに気付きましたが、アニメーションが再生されたり、デリゲートが呼び出されたりすることはありません。さらに恐ろしいのは、次のページをパンしようとすると、インデックス1が再度呼び出されることです。
これはUIPageViewControllerのバグである可能性があります。