UIPageViewController简介

UIPageViewController是iOS 5.0之后提供的一个分页控件可以实现图片轮播效果和翻书效果.使用起来也很简单方便.

UIPageViewController使用

初始化

进入系统API你可以找到iOS SDK提供的初始化方法

- (instancetype)initWithTransitionStyle:(UIPageViewControllerTransitionStyle)stylenavigationOrientation:(UIPageViewControllerNavigationOrientation)navigationOrientationoptions:(nullable NSDictionary<NSString *, id> *)options NS_DESIGNATED_INITIALIZER;
复制代码

初始化方法提供三个参数:

  1. style: 这个参数是UIPageViewController翻页的过渡样式,系统提供了两种过度样式,分别是
  1. UIPageViewControllerTransitionStylePageCurl : 卷曲样式类似翻书效果
  2. UIPageViewControllerTransitionStyleScroll : UIScrollView滚动效果
  1. navigationOrientation: 这个参数是UIPageViewController导航方向,系统提供了两种方式,分别是
  1. UIPageViewControllerNavigationOrientationHorizontal : 水平导航方式
  2. UIPageViewControllerNavigationOrientationVertical : 垂直导航方式
  1. options: 这个参数是可选的,传入的是对UIPageViewController的一些配置组成的字典,不过这个参数只能以UIPageViewControllerOptionSpineLocationKey和UIPageViewControllerOptionInterPageSpacingKey这两个key组成的字典.
  1. UIPageViewControllerOptionSpineLocationKey 这个key只有在style是翻书效果UIPageViewControllerTransitionStylePageCurl的时候才有作用, 它定义的是书脊的位置,值对应着UIPageViewControllerSpineLocation这个枚举项,不要定义错了哦.
  2. UIPageViewControllerOptionInterPageSpacingKey这个key只有在style是UIScrollView滚动效果UIPageViewControllerTransitionStyleScroll的时候才有作用, 它定义的是两个页面之间的间距(默认间距是0).

除了初始化方法系统还提供了一个属性

@property (nonatomic, getter=isDoubleSided) BOOL doubleSided; // Default is 'NO'.
复制代码

这个属性默认为NO,如果我们当前屏幕仅展示一个页面那么不用设置这个属性,如果设置了UIPageViewControllerSpineLocationMid这个选项,效果是翻开的书这样屏幕展示的就是两个页面,这个属性就必须设置为YES了.

此外还有一个重要方法:

- (void)setViewControllers:(nullable NSArray<UIViewController *> *)viewControllersdirection:(UIPageViewControllerNavigationDirection)directionanimated:(BOOL)animatedcompletion:(void (^ __nullable)(BOOL finished))completion;复制代码

这个方法是设置UIPageViewController初始显示的页面,如果doubleSided设为YES了,那么viewControllers这个参数至少包含两个页面.

数据源和代理

UIPageViewController类似UITableViewController机制可以设置数据源和代理.

数据源 <UIPageViewControllerDataSource>

iOS SDK提供了四个数据源方法,其中两个为@required,另外两个是@optional.

@required

- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewControllerviewControllerBeforeViewController:(UIViewController *)viewController;
复制代码

这个方法是返回前一个页面,如果返回为nil,那么UIPageViewController就会认为当前页面是第一个页面不可以向前滚动或翻页

- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewControllerviewControllerAfterViewController:(UIViewController *)viewController;
复制代码

这个方法是下一个页面,如果返回为nil,那么UIPageViewController就会认为当前页面是最后一个页面不可以向后滚动或翻页

代理 <UIPageViewControllerDelegate>

iOS SDK提供了五个代理方法:

// Sent when a gesture-initiated transition begins.
- (void)pageViewController:(UIPageViewController *)pageViewController
willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers NS_AVAILABLE_IOS(6_0);
复制代码

这个方法是UIPageViewController开始滚动或翻页的时候触发

// Sent when a gesture-initiated transition ends. The 'finished' parameter indicates whether the animation finished, while the 'completed' parameter indicates whether the transition completed or bailed out (if the user let go early).
- (void)pageViewController:(UIPageViewController *)pageViewControllerdidFinishAnimating:(BOOL)finishedpreviousViewControllers:(NSArray<UIViewController *> *)previousViewControllerstransitionCompleted:(BOOL)completed;
复制代码

这个方法是在UIPageViewController结束滚动或翻页的时候触发

// Delegate may specify a different spine location for after the interface orientation change. Only sent for transition style 'UIPageViewControllerTransitionStylePageCurl'.
// Delegate may set new view controllers or update double-sided state within this method's implementation as well.
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewControllerspineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation __TVOS_PROHIBITED;
复制代码

这个方法是在style是UIPageViewControllerTransitionStylePageCurl 并且横竖屏状态变化的时候触发,我们可以重新设置书脊的位置,比如如果屏幕是竖屏状态的时候我们就设置书脊位置是UIPageViewControllerSpineLocationMin或UIPageViewControllerSpineLocationMax, 如果屏幕是横屏状态的时候我们可以设置书脊位置是UIPageViewControllerSpineLocationMid

- (UIInterfaceOrientationMask)pageViewControllerSupportedInterfaceOrientations:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
- (UIInterfaceOrientation)pageViewControllerPreferredInterfaceOrientationForPresentation:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
复制代码

这两个方法设置了UIPageViewController支持的屏幕类型

实现效果

翻书效果

直接上代码和效果

ViewController的.m代码如下:

@interface ViewController () <UIPageViewControllerDelegate, UIPageViewControllerDataSource>@property (nonatomic, strong) UIPageViewController *pageViewController;
@property (nonatomic, strong) NSArray *pageContentArray;@end@implementation ViewController#pragma mark - Lazy Load- (NSArray *)pageContentArray {if (!_pageContentArray) {NSMutableArray *arrayM = [[NSMutableArray alloc] init];for (int i = 1; i < 10; i++) {NSString *contentString = [[NSString alloc] initWithFormat:@"This is the page %d of content displayed using UIPageViewController", i];[arrayM addObject:contentString];}_pageContentArray = [[NSArray alloc] initWithArray:arrayM];}return _pageContentArray;
}#pragma mark - Life Cycle- (void)viewDidLoad {[super viewDidLoad];// 设置UIPageViewController的配置项
//    NSDictionary *options = @{UIPageViewControllerOptionInterPageSpacingKey : @(20)};NSDictionary *options = @{UIPageViewControllerOptionSpineLocationKey : @(UIPageViewControllerSpineLocationMin)};// 根据给定的属性实例化UIPageViewController_pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurlnavigationOrientation:UIPageViewControllerNavigationOrientationHorizontaloptions:options];// 设置UIPageViewController代理和数据源_pageViewController.delegate = self;_pageViewController.dataSource = self;// 设置UIPageViewController初始化数据, 将数据放在NSArray里面// 如果 options 设置了 UIPageViewControllerSpineLocationMid,注意viewControllers至少包含两个数据,且 doubleSided = YESContentViewController *initialViewController = [self viewControllerAtIndex:0];// 得到第一页NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];[_pageViewController setViewControllers:viewControllersdirection:UIPageViewControllerNavigationDirectionReverseanimated:NOcompletion:nil];// 设置UIPageViewController 尺寸_pageViewController.view.frame = self.view.bounds;// 在页面上,显示UIPageViewController对象的View[self addChildViewController:_pageViewController];[self.view addSubview:_pageViewController.view];}#pragma mark - UIPageViewControllerDataSource And UIPageViewControllerDelegate#pragma mark 返回上一个ViewController对象- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {NSUInteger index = [self indexOfViewController:(ContentViewController *)viewController];if ((index == 0) || (index == NSNotFound)) {return nil;}index--;// 返回的ViewController,将被添加到相应的UIPageViewController对象上。// UIPageViewController对象会根据UIPageViewControllerDataSource协议方法,自动来维护次序// 不用我们去操心每个ViewController的顺序问题return [self viewControllerAtIndex:index];}#pragma mark 返回下一个ViewController对象- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {NSUInteger index = [self indexOfViewController:(ContentViewController *)viewController];if (index == NSNotFound) {return nil;}index++;if (index == [self.pageContentArray count]) {return nil;}return [self viewControllerAtIndex:index];}#pragma mark - 根据index得到对应的UIViewController- (ContentViewController *)viewControllerAtIndex:(NSUInteger)index {if (([self.pageContentArray count] == 0) || (index >= [self.pageContentArray count])) {return nil;}// 创建一个新的控制器类,并且分配给相应的数据ContentViewController *contentVC = [[ContentViewController alloc] init];contentVC.content = [self.pageContentArray objectAtIndex:index];return contentVC;
}#pragma mark - 数组元素值,得到下标值- (NSUInteger)indexOfViewController:(ContentViewController *)viewController {return [self.pageContentArray indexOfObject:viewController.content];
}@end
复制代码

ContentViewController的.h代码

@interface ContentViewController : UIViewController@property (nonatomic, copy) NSString *content;@end
复制代码

ContentViewController的.m代码

#define kRandomColor ([UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1.0f])@interface ContentViewController ()@property (nonatomic, strong) UILabel *contentLabel;@end@implementation ContentViewController- (void)viewDidLoad{[super viewDidLoad];self.view.backgroundColor = kRandomColor;_contentLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 50, self.view.bounds.size.width, 100)];_contentLabel.numberOfLines = 0;_contentLabel.backgroundColor = kRandomColor;[self.view addSubview:_contentLabel];
}- (void) viewWillAppear:(BOOL)paramAnimated{[super viewWillAppear:paramAnimated];_contentLabel.text = _content;
}@end
复制代码

滚动效果

关于滚动效果只需将初始化配置修改一下即可:

    // 设置UIPageViewController的配置项NSDictionary *options = @{UIPageViewControllerOptionInterPageSpacingKey : @(20)};
//    NSDictionary *options = @{UIPageViewControllerOptionSpineLocationKey : @(UIPageViewControllerSpineLocationMin)};// 根据给定的属性实例化UIPageViewController_pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScrollnavigationOrientation:UIPageViewControllerNavigationOrientationHorizontaloptions:options];
复制代码

UIPageViewController 总结

关于UIPageViewController的使用就介绍这么多,关键点在于UIPageViewController的配置项的设置以及数据源的控制. 希望这篇文章会对你有所帮助 Demo地址 https://github.com/Herb-Sun/UIPageViewControllerDemo

转载于:https://juejin.im/post/5aa53fb9f265da239376b346

UIPageViewController教程相关推荐

  1. 知识点归档,博客记录

    由于本人能力有限,难免有错,欢迎批评.指正.补充,目录请看右下角 Foundation复习 利用category + runtime + 异常的捕获 来写一个防止崩溃的框架 扩展(Extension) ...

  2. AsyncDisplayKit2.0教程(上)

    原文:AsyncDisplayKit 2.0 Tutorial: Getting Started 作者: Luke Parham 译者:kmyhy "Art is anything you ...

  3. SwiftUI 官方教程 (九)

    由于 API 变动,此文章部分内容已失效,最新完整中文教程及代码请查看 https://github.com/WillieWangWei/SwiftUI-Tutorials 微信技术群 SwiftUI ...

  4. SwiftUI官方教程解读

    原文链接:https://www.jianshu.com/p/ecfdbea7a0ed SwiftUI简介 SwiftUI是wwdc2019发布的一个新的UI框架,通过声明和修改视图来布局UI和创建流 ...

  5. 使用Docker搭建svn服务器教程

    使用Docker搭建svn服务器教程 svn简介 SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很 ...

  6. mysql修改校对集_MySQL 教程之校对集问题

    本篇文章主要给大家介绍mysql中的校对集问题,希望对需要的朋友有所帮助! 推荐参考教程:<mysql教程> 校对集问题 校对集,其实就是数据的比较方式. 校对集,共有三种,分别为:_bi ...

  7. mysql备份psb文件怎么打开_Navicat for MySQL 数据备份教程

    原标题:Navicat for MySQL 数据备份教程 一个安全和可靠的服务器与定期运行备份有密切的关系,因为错误有可能随时发生,由攻击.硬件故障.人为错误.电力中断等都会照成数据丢失.备份功能为防 ...

  8. php rabbmq教程_RabbitMQ+PHP 教程一(Hello World)

    介绍 RabbitMQ是一个消息代理器:它接受和转发消息.你可以把它当作一个邮局:当你把邮件放在信箱里时,你可以肯定邮差先生最终会把邮件送到你的收件人那里.在这个比喻中,RabbitMQ就是这里的邮箱 ...

  9. 【置顶】利用 NLP 技术做简单数据可视化分析教程(实战)

    置顶 本人决定将过去一段时间在公司以及日常生活中关于自然语言处理的相关技术积累,将在gitbook做一个简单分享,内容应该会很丰富,希望对你有所帮助,欢迎大家支持. 内容介绍如下 你是否曾经在租房时因 ...

最新文章

  1. 易宝典——玩转O365中的EXO服务 之四十 创建就地电子数据展示搜索
  2. 在ThoughtWorks工作两个多月的总结
  3. USACO Training Section 1.1 Your Ride Is Here
  4. 让钱生钱!商人赚钱的6条方法
  5. BUAA-OO-2019 第三单元总结
  6. java跨库调用存储_java-调用spring数据其余存储库方法不会返回...
  7. Linux中如何理解组的分类,Linux中用户和组管理
  8. 1304: 防御导弹 (未完)
  9. chrome frame解决IE9一下不兼容问题
  10. 线性代数学习指导与MATLAB编程实践,线性代数学习指导与MATLAB编程实践(邵建峰)...
  11. 麒麟软件、麒麟操作系统、银河麒麟、中标麒麟、优麒麟、国产操作系统下载。
  12. 推荐系统系列之隐语义模型
  13. QQ被盗是怎么一回事?
  14. TCP三次握手中SYN,ACK,Seq含义
  15. Cisco nat inside接口,outside接口,nvi接口的区别
  16. android app 三星s8 适配问题 和 meta-data 动态修改
  17. GNSS原理与应用(五)——GPS卫星信号
  18. 标自然段的序号格式_正确的序号及标点使用格式
  19. 关于理财年轻人正在跑步入场
  20. 惠州市计算机网络学校有哪些,惠州市初中学校排行榜

热门文章

  1. 亚马逊首席技术官预测2021年将改变世界的八大技术趋势
  2. 一文剖析2020年最火十大物联网应用|IoT Analytics 年度重磅报告出炉!
  3. 传感器的“脖子”卡在哪儿?
  4. 10年后的计算机会是怎样的?
  5. IBM发布未来五年五大科技预测
  6. 做了7年软件工程师,从500多场技术面试中学到了什么?
  7. 这个勒索软件也太菜了!
  8. 对不起,我的代码评审毁了一个程序员!
  9. “硅谷之父”传奇:拯救斯坦福大学、培养大批高科技人才、指导创立惠普
  10. Hyperledger Fabric Docker 文件路径权限