前言
由于公司要開發(fā)一款小說類閱讀APP肆捕,其中體驗上非常重要的一點便是翻頁效果。為了實現翻頁效果舵变,我查詢了很多資料后選擇使用了UIPageViewController芳杏。原因很簡單,使用方便抡柿,功能強大舔琅,開發(fā)速度快。首先洲劣,我們先看看翻頁效果圖:
結構
在使用UIPageViewController前备蚓,我們應該先搞清楚它的層次結構。(這里是我在使用過程中的理解囱稽,如有不對郊尝,歡迎指出)。
UIPageViewController作為子控制器加載在viewController上粗悯。作為文本控制器的容器虚循,且提供翻頁的動畫效果。
創(chuàng)建一個TextViewController样傍,用來顯示文本,裝入pageViewController中铺遂。
所以衫哥,pageViewController只是提供一個翻頁特效的容器,真正顯示在界面上的是里面的TextViewController襟锐。到這里是我對pageViewController有一個初步的理解撤逢。
使用
1.初始化
- (instancetype)initWithTransitionStyle:(UIPageViewControllerTransitionStyle)style navigationOrientation:(UIPageViewControllerNavigationOrientation)navigationOrientation options:(nullable NSDictionary*)options
UIPageViewController 為我們提供了2種翻頁樣式,一種是擬真一種是滾動粮坞。只需要使用系統(tǒng)的構造方法返回一個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;
從聲明中我們不難發(fā)現返回的是一個UIViewController對象媳叨,這個對象將重新裝入pageViewController中腥光,從而顯示在界面上。其中參數中的viewController為當前顯示的控制器(這個參數在使用doubleSided屬性時非常重要糊秆,后面會講到)武福。知道這2個方法的作用后,pageViewController使用起來就非常簡單了痘番。
并且這個方法執(zhí)行以后捉片,之前pageViewController里的控制器將被釋放,所以pageViewController.viewControllers同樣只裝了1個viewController汞舱。
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerAfterViewController:(UIViewController *)viewController {
//返回即將顯示的控制器
BookTextController *vc = [BookTextController new];
return vc;
}
還有一個非常有用的代理界睁,它在動畫執(zhí)行完畢后被調用,在controller切換完成后兵拢,我們可以在這個代理中進行一些后續(xù)操作翻斟。例如用UIPageViewController實現輪播分頁等功能。
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray*)previousViewControllers transitionCompleted:(BOOL)completed;
到這里pageViewController的基本使用已經差不多了说铃。通過合理的設置访惜,我們很容易就可以實現一個翻頁效果。但是在開發(fā)閱讀軟件中我還遇到一個非常嚴重的體驗問題腻扇。在翻頁的時候债热,書頁背面的顏色默認為白色。在黑夜模式中非常“辣眼睛”幼苛!
窒篱。
3.解決翻頁模式書頁背面“辣眼睛”->doubleSided
顧名思義,doubleSided這個屬性開啟后舶沿,書頁的正反兩面都將顯示文本墙杯。
開啟這個屬性后,dataSource中的那兩個方法會執(zhí)行2次括荡。
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController;
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController;
第一次執(zhí)行viewController和之前一樣是正在翻動的書頁的正面高镐,第二次執(zhí)行時viewController則是第一次return出去的ViewController,即翻動書頁的背面畸冲。這樣就會導致一個非常嚴重的問題嫉髓,書頁正面頁碼不連續(xù)!“消失”的那一頁顯示在了上一頁背面
那么邑闲,如何來優(yōu)化這個問題呢算行?方法非常簡單,我們再創(chuàng)建一個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主要就是理解其層次結構和代理方法調用時機类少。作為容器加載各式各樣的顯示控制器叙身。在此特別感謝一起開發(fā)閱讀APP的戰(zhàn)友小明同學 @GeekDmm 提供的豐富資料。
希望這篇文章可以幫到你硫狞。