UIPageViewController使用 分享筆記

前言

由于公司要開(kāi)發(fā)一款小說(shuō)類閱讀APP,其中體驗(yàn)上非常重要的一點(diǎn)便是翻頁(yè)效果。為了實(shí)現(xiàn)翻頁(yè)效果,我查詢了很多資料后選擇使用了UIPageViewController。原因很簡(jiǎn)單,使用方便,功能強(qiáng)大,開(kāi)發(fā)速度快。首先,我們先看看翻頁(yè)效果圖:

翻頁(yè)效果展示圖

結(jié)構(gòu)

在使用UIPageViewController前,我們應(yīng)該先搞清楚它的層次結(jié)構(gòu)。(這里是我在使用過(guò)程中的理解,如有不對(duì),歡迎指出)。


pageviewcontroller層次展示圖

UIPageViewController作為子控制器加載在viewController上。作為文本控制器的容器,且提供翻頁(yè)的動(dòng)畫效果。

創(chuàng)建一個(gè)TextViewController,用來(lái)顯示文本,裝入pageViewController中。

所以,pageViewController只是提供一個(gè)翻頁(yè)特效的容器,真正顯示在界面上的是里面的TextViewController。到這里是我對(duì)pageViewController有一個(gè)初步的理解。

使用

1.初始化

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

UIPageViewController 為我們提供了2種翻頁(yè)樣式,一種是擬真一種是滾動(dòng)。只需要使用系統(tǒng)的構(gòu)造方法返回一個(gè)UIPageViewController的對(duì)象。并且設(shè)置它的代理和數(shù)據(jù)源并把它加入到控制器中就可以了

pageViewController.delegate = self;

pageViewController.dataSource = self;

[self addChildViewController:pageViewController];

[self.view addSubview:pageViewController.view];

通過(guò)提供的set方法將textController裝入pageViewController中,這個(gè)set方法提供了一種樣式,決定翻頁(yè)是縱向還是橫向。

typedef NS_ENUM(NSInteger, UIPageViewControllerNavigationDirection) {

UIPageViewControllerNavigationDirectionForward,//橫向,像書一樣

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

2.delegate和dataSource

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

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

從聲明中我們不難發(fā)現(xiàn)返回的是一個(gè)UIViewController對(duì)象,這個(gè)對(duì)象將重新裝入pageViewController中,從而顯示在界面上。其中參數(shù)中的viewController為當(dāng)前顯示的控制器(這個(gè)參數(shù)在使用doubleSided屬性時(shí)非常重要,后面會(huì)講到)。知道這2個(gè)方法的作用后,pageViewController使用起來(lái)就非常簡(jiǎn)單了。

并且這個(gè)方法執(zhí)行以后,之前pageViewController里的控制器將被釋放,所以pageViewController.viewControllers同樣只裝了1個(gè)viewController。

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

還有一個(gè)非常有用的代理,它在動(dòng)畫執(zhí)行完畢后被調(diào)用,在controller切換完成后,我們可以在這個(gè)代理中進(jìn)行一些后續(xù)操作。例如用UIPageViewController實(shí)現(xiàn)輪播分頁(yè)等功能。

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

到這里pageViewController的基本使用已經(jīng)差不多了。通過(guò)合理的設(shè)置,我們很容易就可以實(shí)現(xiàn)一個(gè)翻頁(yè)效果。但是在開(kāi)發(fā)閱讀軟件中我還遇到一個(gè)非常嚴(yán)重的體驗(yàn)問(wèn)題。在翻頁(yè)的時(shí)候,書頁(yè)背面的顏色默認(rèn)為白色。在黑夜模式中非常“辣眼睛”

黑夜模式書頁(yè)背面為白色 ![Uploading 1F5EC677-326D-4BAF-96D6-5A885FA07C9F_639563.png . . .]

3.解決翻頁(yè)模式書頁(yè)背面“辣眼睛”->doubleSided

顧名思義,doubleSided這個(gè)屬性開(kāi)啟后,書頁(yè)的正反兩面都將顯示文本。

開(kāi)啟這個(gè)屬性后,dataSource中的那兩個(gè)方法會(huì)執(zhí)行2次。

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

第一次執(zhí)行viewController和之前一樣是正在翻動(dòng)的書頁(yè)的正面,第二次執(zhí)行時(shí)viewController則是第一次return出去的ViewController,即翻動(dòng)書頁(yè)的背面。這樣就會(huì)導(dǎo)致一個(gè)非常嚴(yán)重的問(wèn)題,書頁(yè)正面頁(yè)碼不連續(xù)!“消失”的那一頁(yè)顯示在了上一頁(yè)背面

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

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

那么,如何來(lái)優(yōu)化這個(gè)問(wèn)題呢?方法非常簡(jiǎn)單,我們?cè)賱?chuàng)建一個(gè)BackViewController(這里參考了github上一個(gè)demo:
https://github.com/mattabras/DoubleSidedPageViewController
BackViewController源碼可以直接去上面下載。)

BackViewController上只有一個(gè)大小為屏幕大小的UIImageView,在第一次進(jìn)入時(shí),將參數(shù)viewController的view作為圖片設(shè)置到BackViewController的UIImageView里。返回給pageViewController。第二次才返回要顯示的viewController。

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
      viewControllerBeforeViewController:(UIViewController *)viewController {
    /**
     *  backviewcontroller->截屏當(dāng)前控制器view,顯示在當(dāng)前頁(yè)背面
     */
    if([viewController isKindOfClass:[BookTextController class]]) {
        self.currentViewController = viewController;
        
        LZBackViewController *backViewController = [LZBackViewController new];
        [backViewController updateWithViewController:viewController];
        return backViewController;
    }
    /**
     *  重新加載新的一章或一頁(yè)到lzbooktextcontroller上 并返回給pageviewcontroller
     */    
    LZBackViewController *showVc =  (LZBackViewController *)self.currentViewController;
    return showVc;
}

到這里我們解決了黑夜模式書頁(yè)背面辣眼睛的體驗(yàn)問(wèn)題了。

小結(jié)

使用UIPageViewController主要就是理解其層次結(jié)構(gòu)和代理方法調(diào)用時(shí)機(jī)。作為容器加載各式各樣的顯示控制器。在此特別感謝一起開(kāi)發(fā)閱讀APP的戰(zhàn)友小明同學(xué) @GeekDmm 提供的豐富資料。
希望這篇文章可以幫到你。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,701評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 178,691評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 63,974評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,694評(píng)論 6 413
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 56,026評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 43,193評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,719評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,668評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,846評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 35,255評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 36,592評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,394評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容