UIPageViewController是iOS5之后,蘋果再度給提供的一個強大的類。用以實現類似翻頁效果。
代碼實現:
創建Datasource數組部分:
1 // 首先懶加載翻頁控制器 2 #pragma mark - Lazy Methods 3 - (UIPageViewController *)pageVC { 4 if (!_pageVC) { 5 NSDictionary *option =\ 6 [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:UIPageViewControllerSpineLocationMin] forKey:UIPageViewControllerOptionSpineLocationKey]; 7 _pageVC =\ 8 [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:option]; 9 _pageVC.delegate = self; 10 _pageVC.dataSource = self; 11 } 12 return _pageVC; 13 }
1 // 接下來,構造數據 2 #pragma mark - View lifeCycle 3 - (void)viewDidLoad { 4 [super viewDidLoad]; 5 // 構造數據 6 [self buildData]; 7 } 8 9 // 構造數據 10 - (void)buildData { 11 // 構造數據 12 self.dataArray = [@[@"1", @"2", @"3", @"4", @"5"] mutableCopy]; 13 14 [self.view addSubview:self.pageVC.view]; 15 [self addChildViewController:self.pageVC]; 16 17 HHDataController *dataVC = [self dataViewControllerAtIndex:0]; 18 [self.pageVC setViewControllers:@[dataVC] 19 direction:UIPageViewControllerNavigationDirectionForward 20 animated:YES 21 completion:nil]; 22 }
UIPageViewControllerDataSource 數據源方法觸發條件:點擊或者滑動翻頁時;
1 #pragma mark - UIPageViewControllerDataSource Methods 2 /** 3 * @brief 點擊或滑動 UIPageViewController 左側邊緣時觸發 4 * 5 * @param pageViewController 翻頁控制器 6 * @param viewController 當前控制器 7 * 8 * @return 返回前一個視圖控制器 9 */ 10 - (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController 11 viewControllerBeforeViewController:(UIViewController *)viewController { 12 // 計算當前 viewController 數據在數組中的下標 13 NSUInteger index = [self.dataArray indexOfObject:((HHDataController *)viewController).imageName]; 14 15 // index 為 0 表示已經翻到最前頁 16 if (index == 0 || 17 index == NSNotFound) { 18 return nil; 19 } 20 21 // 下標自減 22 index --; 23 24 return [self dataViewControllerAtIndex:index]; 25 } 26 27 /** 28 * @brief 點擊或滑動 UIPageViewController 右側邊緣時觸發 29 * 30 * @param pageViewController 翻頁控制器 31 * @param viewController 當前控制器 32 * 33 * @return 返回下一個視圖控制器 34 */ 35 - (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController 36 viewControllerAfterViewController:(UIViewController *)viewController { 37 // 計算當前 viewController 數據在數組中的下標 38 NSUInteger index = [self.dataArray indexOfObject:((HHDataController *)viewController).imageName]; 39 40 // index為數組最末表示已經翻至最后頁 41 if (index == NSNotFound || 42 index == (self.dataArray.count - 1)) { 43 return nil; 44 } 45 46 // 下標自增 47 index ++; 48 49 return [self dataViewControllerAtIndex:index]; 50 }
僅僅這樣,可以簡單的實現翻頁的效果。但是,如果快速的翻頁,系統就會出現如下warning
2016-03-15 13:55:47.342 UIPageViewController示例[19649:1900548] Unbalanced calls to begin/end appearance transitions for <HHDataController: 0x7f8982d38060>.
原因:上次動畫還沒結束,然后又開始了新的動畫。 這樣就導致不能成功切換頁面,而是一個白色無內容的頁面。
解決方案:動畫執行過程中,關閉翻頁控制器視圖的用戶交互;動畫執行完畢之后再次打開。
1 #pragma mark - UIPageViewController Methods 2 /** 3 * @brief 轉場動畫即將開始 4 * 5 * @param pageViewController 翻頁控制器 6 * @param pendingViewControllers 即將展示的控制器 7 */ 8 - (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers { 9 // 轉場動畫未執行完,關閉用戶交互 10 pageViewController.view.userInteractionEnabled = NO; 11 } 12 13 /** 14 * @brief 該方法會在 UIPageViewController 翻頁效果出發之后,尚未完成時執行 15 * 16 * @param pageViewController 翻頁控制器 17 * @param finished 動畫完成 18 * @param previousViewControllers 前一個控制器(非當前) 19 * @param completed 轉場動畫執行完 20 */ 21 - (void)pageViewController:(UIPageViewController *)pageViewController 22 didFinishAnimating:(BOOL)finished 23 previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers 24 transitionCompleted:(BOOL)completed { 25 if (completed && finished) { 26 // 轉場動畫完成,開啟用戶交互 27 pageViewController.view.userInteractionEnabled = YES; 28 } 29 }
尊重作者勞動成果,轉載請注明: 【kingdev】