UIPageViewController
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】