UIPageViewController使用和控件的封裝

背景

我們經(jīng)常會(huì)遇到一個(gè)場(chǎng)景,就是同時(shí)有幾個(gè)視圖需要左右滑動(dòng)顯示。大家可能會(huì)通過(guò)UIScrollview來(lái)實(shí)現(xiàn),也能實(shí)現(xiàn)。但是如果不自己實(shí)現(xiàn)一些懶加載、緩存其實(shí)對(duì)性能還是有浪費(fèi)的。接下來(lái)我們就讓U閃亮登場(chǎng)。UIPageViewController加載不同的UIViewController可以有效的將不同邏輯進(jìn)行了分離,減輕了總UIViewController的負(fù)擔(dān)。
我通過(guò)UIPageViewController簡(jiǎn)單封裝了一個(gè)工具,就是加載不同的視圖,支持上下滑動(dòng)、左右滑動(dòng)。并且具有懶加載和緩存的功能,在一定程度上提高了性能。

初始化

    self.array = @[[FirstViewController class],[SecondViewController class],[FirstViewController class]];
//實(shí)例化UIPageViewController,并且指定方向和動(dòng)畫(huà)??梢栽O(shè)置options。UIPageViewControllerOptionInterPageSpacingKey兩個(gè)視圖的間距
    UIPageViewController *page = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:@{UIPageViewControllerOptionInterPageSpacingKey:@10}];
    page.delegate = self;
    page.dataSource = self;
typedef NS_ENUM(NSInteger, UIPageViewControllerTransitionStyle) {
    UIPageViewControllerTransitionStylePageCurl = 0, //翻書(shū)的效果
    UIPageViewControllerTransitionStyleScroll = 1 // 正常滑動(dòng)切換效果
};
typedef NS_ENUM(NSInteger, UIPageViewControllerNavigationDirection) {
    UIPageViewControllerNavigationDirectionForward,
    UIPageViewControllerNavigationDirectionReverse
};
其實(shí)這兩個(gè)就是一對(duì)。如果是左右滑動(dòng)的話,一個(gè)代表從左到右,另一個(gè)就是從右到左;如果上下滑動(dòng),一個(gè)代表從上到下,另一個(gè)就是從下到上。
//設(shè)置當(dāng)前顯示ViewController,這里通過(guò)一個(gè)方法集中生成,其實(shí)也是做到緩存功能。
    [page setViewControllers:@[[self private_viewControllerForPage:0]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
    [self addChildViewController:page];
    [self.view addSubview:page.view];
    [page didMoveToParentViewController:self];
//實(shí)例化UIViewController,并且緩存起來(lái)
- (UIViewController *)private_viewControllerForPage:(NSUInteger)pageIndex{
    if (pageIndex<self.pageViewControllerClasses.count) {
        if (pageIndex<self.cacheViewControllerArray.count) {
            return self.cacheViewControllerArray[pageIndex];
        }else{
            Class controllerClass =  self.pageViewControllerClasses[pageIndex];
            UIViewController *controller = [[controllerClass alloc] init];
            [self.cacheViewControllerArray insertObject:controller atIndex:pageIndex];
            return controller;
        }
    }
    return nil;
    
}
- (NSInteger)private_indexOfViewController:(UIViewController *)viewController{
    NSInteger index = [self.cacheViewControllerArray indexOfObject:viewController];
    return index;
}

代理方法

//向后滑動(dòng)的時(shí)候,調(diào)用此方法。獲取之前顯示過(guò)的UIViewController
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController{
    NSInteger currentIndex = [self private_indexOfViewController:viewController];
    if (currentIndex>0) {
        return [self private_viewControllerForPage:currentIndex-1];
    }
    return nil;
}
//向前滑動(dòng)的時(shí)候,調(diào)用此方法。獲取之后要顯示的UIViewController
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{
    NSInteger currentIndex = [self private_indexOfViewController:viewController];
    if (currentIndex>=0) {
        return [self private_viewControllerForPage:currentIndex+1];
    }
    return nil;
}
//滑動(dòng)結(jié)束后回調(diào)此方法
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed{
    if (completed&&self.YTOPageViewControllerPageChanged) {
        self.YTOPageViewControllerPageChanged([self private_indexOfViewController:pageViewController.viewControllers.firstObject]);
    }
}

上邊就是UIPageViewController的基本用法。大家可以自行去探索一下。其實(shí)挺好玩的,也可以實(shí)現(xiàn)一下顯示兩個(gè)視圖,看起來(lái)就是一本打開(kāi)的書(shū)的效果。
下邊是我封裝的一個(gè)工具類,大家可以參考一下。只要傳入你需要顯示的UIViewController
的class名字就可以。

效果圖

效果.png

控件地址

大家覺(jué)著有用別忘了star一下哦!
YTOSectionsViewController

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,001評(píng)論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,228評(píng)論 4 61
  • 這也算是我的第一篇隨筆,文辭定是很難入眼,所以也只希望其內(nèi)容能夠有那么一點(diǎn)新意。 古話說(shuō),三歲看到老,我認(rèn)為其實(shí)并...
    孔瑞杰閱讀 2,588評(píng)論 0 2
  • 本文就要介紹Win7上Eclipse環(huán)境的配置,主要涉及: ① 當(dāng)前最新版 eclipse luna的下載,安裝,...
    宇文臭臭閱讀 291評(píng)論 0 1
  • 一不留神,史上超長(zhǎng)假期已經(jīng)過(guò)去了一半,方不方,慌不慌?這幾天你是和床親密約會(huì),還是去巡視祖國(guó)大好河山了? 我知道有...
    詩(shī)畫(huà)浙江閱讀 310評(píng)論 0 0

友情鏈接更多精彩內(nèi)容