最近在一个项目中需要一种以翻书的形式来展示图片的功能,在查阅了一些资料后,初步了解了UIPageViewController,查到的资料都是比较久之前的,有的还是在MRC的,在使用的过程中也遇到一些问题,最终磕磕绊绊也算是实现了这个功能,现将使用的一些积累整理一下,也算是一种记录吧.其中借用了一些网上的代码段,如有雷同,感谢分享!!
本文只介绍简单的使用,只针对初次使用UIPageViewController,高手请绕行!
理论的介绍及更深入的功能请自行查阅相关资料!
UIPageViewController主要是一个实现类似翻书的效果的控件,其中主要用到了它的两个数据源方法:
//返回前一个视图 - (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController //返回下一个视图 - (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
需要先导入数据源代理
UIPageViewControllerDataSource下面初始化UIPageViewController,在初始化的时候传入的options中,可以选择是单页显示,还是双页显示
// UIPageViewControllerSpineLocationMin 单页显示 // UIPageViewControllerSpineLocationMid 双页显示
NSDictionary * options = [NSDictionary dictionaryWithObject:[NSNumber numberWithInteger:UIPageViewControllerSpineLocationMid] forKey:UIPageViewControllerOptionSpineLocationKey]; self.LQQ_pageViewController = [[UIPageViewController alloc]initWithTransitionStyle:(UIPageViewControllerTransitionStylePageCurl) navigationOrientation:(UIPageViewControllerNavigationOrientationHorizontal) options:options];设置数据源代理
self.LQQ_pageViewController.dataSource = self;获取数据源视图,因为我的是双页显示的,所以先获取两页,如果是单页,先初始化获取一个就行
LQQContentViewController * initialViewController = [self viewCintrollerAtIndex:0]; LQQContentViewController * endViewController = [self viewCintrollerAtIndex:1];
NSArray * viewControllers = [NSArray arrayWithObjects:initialViewController,endViewController,nil]; [self.LQQ_pageViewController setViewControllers:viewControllers direction:(UIPageViewControllerNavigationDirectionForward) animated:NO completion:nil];添加视图:
[self addChildViewController:self.LQQ_pageViewController]; [self.view addSubview:self.LQQ_pageViewController.view]; [self.LQQ_pageViewController didMoveToParentViewController:self];以上这些可以直接使用,基本不会有多大变化,下面这个是设置 UIPageViewController的frame,
这个可根据自己需求设定,因为我的是横屏显示的,没有做转屏,而是让竖图旋转了90°:
self.LQQ_pageViewController.view.center = CGPointMake(self.view.center.x, self.view.center.y + 32); self.LQQ_pageViewController.view.bounds = CGRectMake(0, 0, self.view.frame.size.height - 104, self.view.frame.size.width - 20); self.LQQ_pageViewController.view.transform = CGAffineTransformMakeRotation(M_PI_2);这样 UIPageViewController的初始化基本就完成了!
因为要多次调用创建数据源视图(这里是LQQContentViewController),所以单独写成一个方法:
//返回一个视图 - (LQQContentViewController *)viewCintrollerAtIndex:(NSUInteger)index { if ([self.LQQ_pageContent count] == 0 || (index >= [self.LQQ_pageContent count])) { return nil; } LQQContentViewController * dataViewController = [[LQQContentViewController alloc]init]; //如果去掉这个if-else 照片无法正常显示,原因暂不明确 if (index == 0 || index == self.LQQ_pageContent.count - 1) { #warning 如果不需要显示第一页和最后一页,就将第一页的背景色与viewController一致,或者隐藏掉,这样才会有看到书的封面和封底的效果 dataViewController.view.backgroundColor = [UIColor greenColor]; } else { #warning 其他页的一些设置,即使不需要设置什么,也要随机设置个背景色或者其他属性,否则会显示不正常 dataViewController.view.backgroundColor = [UIColor purpleColor]; } #warning -- 配置数据源 dataViewController.LQQ_imageView.image = [self.LQQ_pageContent objectAtIndex:index]; //这句必须有,且只能这么写 dataViewController.LQQ_dataObject = [self.LQQ_pageContent objectAtIndex:index]; return dataViewController; }
方法中的LQQ_dataObject属性主要是用于返回当前视图在数据源中的index值的:
//获取当前页的索引 - (NSUInteger)indexOfViewController:(LQQContentViewController*)viewController { return [self.LQQ_pageContent indexOfObject:viewController.LQQ_dataObject]; }
#pragma mark -- UIPageViewController 数据源方法 - (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController { NSUInteger index = [self indexOfViewController:(LQQContentViewController *)viewController]; if (index == 0 || (index == NSNotFound)) { return nil; } index --; return [self viewCintrollerAtIndex:index]; } - (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController { NSUInteger index = [self indexOfViewController:(LQQContentViewController *)viewController]; if (index == NSNotFound) { return nil; } index++; if (index == [self.LQQ_pageContent count]) { return nil; } return [self viewCintrollerAtIndex:index]; }
个人认为是必须要约束其子视图的位置,而不能只是设置其坐标,这块没有深入理解,所以可以选择使用xib,并添加约束;也可以代码创建,添加约束!
#import <UIKit/UIKit.h> @interface LQQContentViewController : UIViewController /** * @author LQQ, 15-12-26 18:12:19 * * 这个属性主要是用于返回创建的对象在数据源数组中的索引,不属于显示的内容,但是必须要有 */ @property (retain,nonatomic)id LQQ_dataObject; /** * @author LQQ, 15-12-26 18:12:51 * * 自定义布局的内容 */ @property (weak, nonatomic) IBOutlet UIImageView *LQQ_imageView; //@property (nonatomic,weak)IBOutlet UIImage *LQQ_image; @end
另外,UIPageViewController也有代理方法,具体的使用请自行参照API!