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】

posted @ 2016-03-15 14:06  Kingdev  阅读(5813)  评论(0编辑  收藏  举报