UIPageViewController使用 分享笔记

前言

由于公司要开发一款小说类阅读APP,其中体验上非常重要的一点便是翻页效果。为了实现翻页效果,我查询了很多资料后选择使用了UIPageViewController。原因很简单,使用方便,功能强大,开发速度快。首先,我们先看看翻页效果图:

翻页效果展示图

结构

在使用UIPageViewController前,我们应该先搞清楚它的层次结构。(这里是我在使用过程中的理解,如有不对,欢迎指出)。


pageviewcontroller层次展示图

UIPageViewController作为子控制器加载在viewController上。作为文本控制器的容器,且提供翻页的动画效果。

创建一个TextViewController,用来显示文本,装入pageViewController中。

所以,pageViewController只是提供一个翻页特效的容器,真正显示在界面上的是里面的TextViewController。到这里是我对pageViewController有一个初步的理解。

使用

1.初始化

- (instancetype)initWithTransitionStyle:(UIPageViewControllerTransitionStyle)style navigationOrientation:(UIPageViewControllerNavigationOrientation)navigationOrientation options:(nullable NSDictionary*)options

UIPageViewController 为我们提供了2种翻页样式,一种是拟真一种是滚动。只需要使用系统的构造方法返回一个UIPageViewController的对象。并且设置它的代理和数据源并把它加入到控制器中就可以了

pageViewController.delegate = self;

pageViewController.dataSource = self;

[self addChildViewController:pageViewController];

[self.view addSubview:pageViewController.view];

通过提供的set方法将textController装入pageViewController中,这个set方法提供了一种样式,决定翻页是纵向还是横向。

typedef NS_ENUM(NSInteger, UIPageViewControllerNavigationDirection) {

UIPageViewControllerNavigationDirectionForward,//横向,像书一样

UIPageViewControllerNavigationDirectionReverse//纵向,像日历一样
};
BookTextController *readerController = [BookTextController new];//展示文本的控制器
    [_pageViewController setViewControllers:@[ readerController ]
                                  direction:UIPageViewControllerNavigationDirectionForward
                                   animated:NO
                                 completion:nil];

2.delegate和dataSource

//向前翻页
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController;

//向后翻页
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController;

从声明中我们不难发现返回的是一个UIViewController对象,这个对象将重新装入pageViewController中,从而显示在界面上。其中参数中的viewController为当前显示的控制器(这个参数在使用doubleSided属性时非常重要,后面会讲到)。知道这2个方法的作用后,pageViewController使用起来就非常简单了。

并且这个方法执行以后,之前pageViewController里的控制器将被释放,所以pageViewController.viewControllers同样只装了1个viewController。

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
       viewControllerAfterViewController:(UIViewController *)viewController {
    //返回即将显示的控制器
    BookTextController *vc = [BookTextController new];
    return vc;
}

还有一个非常有用的代理,它在动画执行完毕后被调用,在controller切换完成后,我们可以在这个代理中进行一些后续操作。例如用UIPageViewController实现轮播分页等功能。

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray*)previousViewControllers transitionCompleted:(BOOL)completed;

到这里pageViewController的基本使用已经差不多了。通过合理的设置,我们很容易就可以实现一个翻页效果。但是在开发阅读软件中我还遇到一个非常严重的体验问题。在翻页的时候,书页背面的颜色默认为白色。在黑夜模式中非常“辣眼睛”

黑夜模式书页背面为白色 ![Uploading 1F5EC677-326D-4BAF-96D6-5A885FA07C9F_639563.png . . .]

3.解决翻页模式书页背面“辣眼睛”->doubleSided

顾名思义,doubleSided这个属性开启后,书页的正反两面都将显示文本。

开启这个属性后,dataSource中的那两个方法会执行2次。

- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController;
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController;

第一次执行viewController和之前一样是正在翻动的书页的正面,第二次执行时viewController则是第一次return出去的ViewController,即翻动书页的背面。这样就会导致一个非常严重的问题,书页正面页码不连续!“消失”的那一页显示在了上一页背面

1F5EC677-326D-4BAF-96D6-5A885FA07C9F.png

9B291FCF-5570-45F3-87DA-940FD207352F.png

那么,如何来优化这个问题呢?方法非常简单,我们再创建一个BackViewController(这里参考了github上一个demo:
https://github.com/mattabras/DoubleSidedPageViewController
BackViewController源码可以直接去上面下载。)

BackViewController上只有一个大小为屏幕大小的UIImageView,在第一次进入时,将参数viewController的view作为图片设置到BackViewController的UIImageView里。返回给pageViewController。第二次才返回要显示的viewController。

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
      viewControllerBeforeViewController:(UIViewController *)viewController {
    /**
     *  backviewcontroller->截屏当前控制器view,显示在当前页背面
     */
    if([viewController isKindOfClass:[BookTextController class]]) {
        self.currentViewController = viewController;
        
        LZBackViewController *backViewController = [LZBackViewController new];
        [backViewController updateWithViewController:viewController];
        return backViewController;
    }
    /**
     *  重新加载新的一章或一页到lzbooktextcontroller上 并返回给pageviewcontroller
     */    
    LZBackViewController *showVc =  (LZBackViewController *)self.currentViewController;
    return showVc;
}

到这里我们解决了黑夜模式书页背面辣眼睛的体验问题了。

小结

使用UIPageViewController主要就是理解其层次结构和代理方法调用时机。作为容器加载各式各样的显示控制器。在此特别感谢一起开发阅读APP的战友小明同学 @GeekDmm 提供的丰富资料。
希望这篇文章可以帮到你。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容