文档章节

iOS翻页视图控制器UIPageViewController的应用

珲少
 珲少
发布于 2016/03/03 19:14
字数 1484
阅读 3714
收藏 16
点赞 1
评论 0

iOS翻页视图控制器UIPageViewController的应用

一、引言

    UIPageViewController是iOS中少见的动画视图控制器之一,通过它既可以创建类似UIScrollView与UIPageControl结合的滚屏视图,也可以创建类似图书效果的炫酷翻页视图。UIPageViewController类似一个视图容器,其中每个具体的视图由各自的ViewController进行维护管理,UIPageViewController只进行协调与动画布置。下图可以很好的展现出UIPageViewControlelr的使用结构:

上图中,UIPageViewControllerDataSource协议为UIPageViewController提供数据支持,DataSource协议提供的数据来自各个ViewContoller自行维护,UIPageViewControllerDelegate中的回调可以对翻页动作,屏幕旋转动作等进行监听。UIPageViewController把从DataSource中获取到的视图数据渲染给View用于当前视图控制器的展示。

二、创建一个UIPageViewController

    首先新建一个类作为翻页视图控制器中具体每一页视图的控制器,使其继承于UIViewController:

ModelViewController.h

#import <UIKit/UIKit.h>
@interface ModelViewController : UIViewController
+(ModelViewController *)creatWithIndex:(int)index;
@property(nonatomic,strong)UILabel * indexLabel;
@end

ModelViewController.m

#import "ModelViewController.h"
@interface ModelViewController ()
@end
@implementation ModelViewController
+(ModelViewController *)creatWithIndex:(int)index{
    ModelViewController * con = [[ModelViewController alloc]init];
    con.indexLabel = [[UILabel alloc]initWithFrame:CGRectMake(110, 200, 100, 30)];
    con.indexLabel.text = [NSString stringWithFormat:@"第%d页",index];
    [con.view addSubview:con.indexLabel];
    return con;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor redColor];
}
@end

在工程模板自带的ViewController.m文件中实现如下代码:

#import "ViewController.h"
#import "ModelViewController.h"
//遵守协议
@interface ViewController ()<UIPageViewControllerDataSource,UIPageViewControllerDelegate>
{
    //翻页视图控制器对象
    UIPageViewController * _pageViewControl;
    //数据源数组
    NSMutableArray * _dataArray;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //进行初始化
    _pageViewControl = [[UIPageViewController alloc]initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:@{UIPageViewControllerOptionSpineLocationKey:@0,UIPageViewControllerOptionInterPageSpacingKey:@10}];
    self.view.backgroundColor = [UIColor greenColor];
    //设置翻页视图的尺寸
    _pageViewControl.view.bounds=self.view.bounds;
    //设置数据源与代理
    _pageViewControl.dataSource=self;
    _pageViewControl.delegate=self;
    //创建初始界面
    ModelViewController * model = [ModelViewController creatWithIndex:1];
    //设置初始界面
    [_pageViewControl setViewControllers:@[model] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];
    //设置是否双面展示
    _pageViewControl.doubleSided = NO;
    _dataArray = [[NSMutableArray alloc]init];
    [_dataArray addObject:model];
    [self.view addSubview:_pageViewControl.view];
}
//翻页控制器进行向前翻页动作 这个数据源方法返回的视图控制器为要显示视图的视图控制器
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController{
    int index = (int)[_dataArray indexOfObject:viewController];
    if (index==0) {
        return nil;
    }else{
        return _dataArray[index-1];
    }
}
//翻页控制器进行向后翻页动作 这个数据源方法返回的视图控制器为要显示视图的视图控制器
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{
    int index = (int)[_dataArray indexOfObject:viewController];
    if (index==9) {
        return nil;
    }else{
        if (_dataArray.count-1>=(index+1)) {
            return _dataArray[index+1];
        }else{
            ModelViewController * model = [ModelViewController creatWithIndex:index+2];
            [_dataArray addObject:model];
            return model;
        }
    }
}
//屏幕旋转触发的代理方法
- (UIPageViewControllerSpineLocation) pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation{
    return UIPageViewControllerSpineLocationMin;
}
//设置分页控制器的分页数
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
    
    return 10;
}
//设置初始的分页点
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController{
    return 0;
}
@end

上面创建了最简单的翻页视图控制器示例,效果如下图:

三、UIPageViewController中方法使用解析

//创建翻页视图控制器对象
- (instancetype)initWithTransitionStyle:(UIPageViewControllerTransitionStyle)style navigationOrientation:(UIPageViewControllerNavigationOrientation)navigationOrientation options:(nullable NSDictionary<NSString *, id> *)options;

上面方法用于创建视图控制器对象,其中UIPageViewControllerTransitionStyle参数设置翻页控制器的风格,枚举如下:

typedef NS_ENUM(NSInteger, UIPageViewControllerTransitionStyle) {
    UIPageViewControllerTransitionStylePageCurl = 0, //类似于书本翻页效果
    UIPageViewControllerTransitionStyleScroll = 1 // 类似于ScrollView的滑动效果
};

如果设置为UIPageViewControllerTransitionStyleCurl,翻页效果如下图所示:

上面初始化方法中的UIPageViewControllerNavigationOrientation属性设置翻页的方向,枚举如下:

typedef NS_ENUM(NSInteger, UIPageViewControllerNavigationOrientation) {
    UIPageViewControllerNavigationOrientationHorizontal = 0,//水平翻页
    UIPageViewControllerNavigationOrientationVertical = 1//竖直翻页
};

options参数用于设置翻页视图控制器的配置字典,其可以设置的配置键值如下:

//这个键需要设置为UIPageViewControllerOptionSpineLocationKey枚举值对应的NSNumber对象 设置翻页控制器的书轴 后面会介绍
NSString * const UIPageViewControllerOptionSpineLocationKey;
//这个键需要设置为NSNumber类型 设置每页视图的间距 用于滚动视图风格的
NSString * const UIPageViewControllerOptionInterPageSpacingKey;

下面是UIPageViewController的一些常用属性与方法:

//设置数据源
@property (nullable, nonatomic, weak) id <UIPageViewControllerDelegate> delegate;
//设置代理
@property (nullable, nonatomic, weak) id <UIPageViewControllerDataSource> dataSource;
//获取翻页风格
@property (nonatomic, readonly) UIPageViewControllerTransitionStyle transitionStyle;
//获取翻页方向
@property (nonatomic, readonly) UIPageViewControllerNavigationOrientation navigationOrientation;
//获取书轴类型
@property (nonatomic, readonly) UIPageViewControllerSpineLocation spineLocation;
//设置是否双面显示
@property (nonatomic, getter=isDoubleSided) BOOL doubleSided;
//设置要显示的视图控制器
- (void)setViewControllers:(nullable NSArray<UIViewController *> *)viewControllers direction:(UIPageViewControllerNavigationDirection)direction animated:(BOOL)animated completion:(void (^ __nullable)(BOOL finished))completion;

上面只有spineLocation属性有些难于理解,其枚举如下:

typedef NS_ENUM(NSInteger, UIPageViewControllerSpineLocation) {
    //对于SCrollView类型的滑动效果 没有书轴 会返回下面这个枚举值
    UIPageViewControllerSpineLocationNone = 0, 
    //以左边或者上边为轴进行翻转 界面同一时间只显示一个View
    UIPageViewControllerSpineLocationMin = 1,  
    //以中间为轴进行翻转 界面同时可以显示两个View
    UIPageViewControllerSpineLocationMid = 2, 
    //以下边或者右边为轴进行翻转 界面同一时间只显示一个View
    UIPageViewControllerSpineLocationMax = 3   
};

将上面的示例代码修改几个地方如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    _pageViewControl = [[UIPageViewController alloc]initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationVertical options:@{UIPageViewControllerOptionSpineLocationKey:@2,UIPageViewControllerOptionInterPageSpacingKey:@10}];
    self.view.backgroundColor = [UIColor greenColor];
    _pageViewControl.view.bounds=self.view.bounds;
    _pageViewControl.dataSource=self;
    _pageViewControl.delegate=self;
    ModelViewController * model = [ModelViewController creatWithIndex:1];
    ModelViewController * model2 = [ModelViewController creatWithIndex:2];
    [_pageViewControl setViewControllers:@[model,model2] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];
    _pageViewControl.doubleSided = YES;
    _dataArray = [[NSMutableArray alloc]init];
    [_dataArray addObject:model];
    [self.view addSubview:_pageViewControl.view];
}
- (UIPageViewControllerSpineLocation) pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation{
    return UIPageViewControllerSpineLocationMid;
}

运行效果如下图所示:

四、UIPageViewControllerDataSource中方法解析

//向前翻页展示的ViewController
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController;
//向后翻页展示的ViewController
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController;
//设置分页控制器的分页点数
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0);
//设置当前分页控制器所高亮的点
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0);

五、UIPageViewControllerDelegate中方法解析

//翻页视图控制器将要翻页时执行的方法
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers NS_AVAILABLE_IOS(6_0);
//翻页动画执行完成后回调的方法
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed;
//屏幕防线改变时回到的方法,可以通过返回值重设书轴类型枚举
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation;

专注技术,热爱生活,交流技术,也做朋友。

——珲少 QQ群:203317592

© 著作权归作者所有

共有 人打赏支持
珲少

珲少

粉丝 836
博文 375
码字总数 440447
作品 0
上海
iOS工程师
移动开发:初学 iOS-UIViewController 心得

初学 iOS,本文翻译了一些 iOS 官网上的 UIViewController 的知识点,如有不到位或不正确的地方,还请指正: 本文所介绍的内容的目标: 理解content view controllers 和 container view con...

OneAPM蓝海讯通
2016/02/24
42
0
iOS开发捷径学习(三)

Storyboard的segue Storyboard中的segue功能强大,是页面跳转与交互的利器。现在就了解下吧。 初始化 segue的三个参数: identifier:唯一标识,用于标识自己 sourceViewController:来源控制...

智小融
01/02
0
0
如何解决UIWebview+UIPageViewController 翻页不流畅的问题

最近在做一个基于IOS的 epub reader, 基本的实现思路就是用UIWebview 显示epub内的xhtml文件。为了实现类似iBooks模拟翻页效果,所以用到了IOS5提供的UIPageViewController 。 具体的实现思...

Larrylu
2013/01/23
1K
0
Tab Bar Controller和Navigation Controller混合使用详细教程

在IPHONE上,NAV和TAB混合使用的案例很多.但很多书籍都没详细介绍这个是怎么使用的.我也找了很久才弄清楚怎么做.现在分享给大家. 1.先建立一个Window-based Application 项目. 2.加入一个Tab...

JohnZr
2012/06/24
0
0
Spring MVC 入门示例讲解

MVC框架是什么 模型-视图-控制器(MVC)是一个众所周知的以设计界面应用程序为基础的设计模式。它主要通过分离模型、视图及控制器在应用程序中的角色将业务逻辑从界面中解耦。通常,模型负责...

枫叶摇曳
2017/08/01
111
0
【翻译】在Ext JS 6通用应用程序中使用既共享又特定于视图的代码

原文:Using Both Shared and View-Specific Code in an Ext JS 6 Universal App 在本文,在展示如何编写Ext JS 6通用应用程序代码以使控制器和视图模型能适用于特定视图又是共享的。 想了解...

tianxiaode2008
2015/08/07
0
0
从需求分析、原型设计到架构再到编码讲解 iPhone应用程序:“Say Hello”

项目需求 写一个iPhone应用程序,要求可以输入名字,点击按钮后,会显示一段文字向输入的名字打招呼,例如输入“宝玉”,显示“你好,宝玉!” 需求分析 这是一个很简单的应用程序,包含一个文...

鉴客
2012/01/10
2K
2
iOS10 UI教程视图的绘制与视图控制器和视图

iOS10 UI教程视图的绘制与视图控制器和视图 iOS10 UI视图的绘制 iOS10 UI教程视图的绘制与视图控制器和视图,在iOS中,有很多的绘图应用。这些应用大多是在UIView上进行绘制的。如果想在一个...

大学霸
2016/11/28
31
0
iphone 开发随笔

这两天继续看了iphone开发秘籍这本书,由于书上介绍的是xcode 3.0 的版本,而我的xcode的版本是4.2,想实践下,总体问题多多 最明显的问题是,xcode 4.2为按钮绑定事件,已经跟xcode 3.0不一样了,...

晨曦之光
2012/03/08
543
0
企业应用架构模式学习(十四):web表现形式

模型-视图-控制器(Model View Controller) MVC 模式是我们目前最常用的模式,它可是起源于20世纪70年代后期,比80后都早。 运行机制 模型:一个表示领域信息的对象,是一个不可见的对象,包...

大风起兮
2013/06/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

NNS域名系统之域名竞拍

0x00 前言 其实在官方文档中已经对域名竞拍的过程有详细的描述,感兴趣的可以移步http://doc.neons.name/zh_CN/latest/nns_protocol.html#id30 此处查阅。 我这里主要对轻钱包开发中会用到的...

暖冰
今天
0
0
32.filter表案例 nat表应用 (iptables)

10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用 10.15 iptables filter表案例: ~1. 写一个具体的iptables小案例,需求是把80端口、22端口、21 端口放行。但是,22端口我...

王鑫linux
今天
0
0
shell中的函数&shell中的数组&告警系统需求分析

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析

影夜Linux
今天
0
0
Linux网络基础、Linux防火墙

Linux网络基础 ip addr 命令 :查看网口信息 ifconfig命令:查看网口信息,要比ip addr更明了一些 centos 7默认没安装ifconfig命令,可以使用yum install -y net-tools命令来安装。 ifconfig...

李超小牛子
今天
1
0
[机器学习]回归--Decision Tree Regression

CART决策树又称分类回归树,当数据集的因变量为连续性数值时,该树算法就是一个回归树,可以用叶节点观察的均值作为预测值;当数据集的因变量为离散型数值时,该树算法就是一个分类树,可以很...

wangxuwei
昨天
1
0
Redis做分布式无锁CAS的问题

因为Redis本身是单线程的,具备原子性,所以可以用来做分布式无锁的操作,但会有一点小问题。 public interface OrderService { public String getOrderNo();} public class OrderRe...

算法之名
昨天
10
0
143. Reorder List - LeetCode

Question 143. Reorder List Solution 题目大意:给一个链表,将这个列表分成前后两部分,后半部分反转,再将这两分链表的节点交替连接成一个新的链表 思路 :先将链表分成前后两部分,将后部...

yysue
昨天
1
0
数据结构与算法1

第一个代码,描述一个被称为BankAccount的类,该类模拟了银行中的账户操作。程序建立了一个开户金额,显示金额,存款,取款并显示余额。 主要的知识点联系为类的含义,构造函数,公有和私有。...

沉迷于编程的小菜菜
昨天
1
0
从为什么别的队伍总比你的快说起

在机场候检排队的时候,大多数情况下,别的队伍都要比自己所在的队伍快,并常常懊悔当初怎么没去那个队。 其实,最快的队伍只能有一个,而排队之前并不知道那个队快。所以,如果有六个队伍你...

我是菜鸟我骄傲
昨天
1
0
分布式事务常见的解决方案

随着互联网的发展,越来越多的多服务相互之间的调用,这时候就产生了一个问题,在单项目情况下很容易实现的事务控制(通过数据库的acid控制),变得不那么容易。 这时候就产生了多种方案: ...

小海bug
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部