UICollectionView嵌套UIViewController实现Pager多页滚动

Pager需求

写在最开始,前段时间在项目中,需要实现多页水平滚动切换不同页面,如上图所示,weex中官方组件不能满足需求,需要三端(H5、Android、iOS)来实现weex自定义组件pager,通过weex调用的方法来代用原生的Pager组件。


本文只抽离了iOS原生部分实现的内容,主要来说明,在iOS客户端是如何实现这种Pager需求的。

UICollectionView嵌套UIViewController实现Pager多页滚动_第1张图片

核心思想

iOS5以后,可以通过addChildViewController将向视图控制器中添加子视图控制器。

示例:

// 自定义view
UIView *view = [[UIView alloc] initWithFrame:CGRectMake((CGRectGetWidth(self.view.frame) - 300) / 2, 50, 300, 300)];
view.backgroundColor = [UIColor orangeColor];
[self.view addSubview:view];

// 向ViewController中的view添加subViewController
UIViewController *subViewController = [[UIViewController alloc] init];
subViewController.view.backgroundColor = [UIColor blueColor];
subViewController.view.frame = CGRectMake(0, 0, CGRectGetWidth(view.frame), CGRectGetHeight(view.frame));
[subViewController willMoveToParentViewController:self];
[self addChildViewController:subViewController];
[subViewController didMoveToParentViewController:self];
[view addSubview:subViewController.view];
UICollectionView嵌套UIViewController实现Pager多页滚动_第2张图片
pager结构

一、 ExamplePagerViewController

ExamplePagerViewController.h文件
#import 
@interface ExamplePagerViewController : UIViewController
@end
ExamplePagerViewController.m文件

基于UIKit控件中的UICollectionView,在Cell中嵌套PagerViewController来实现Pager的需求,如下所示:

#import "ExamplePagerViewController.h"
#import "PagerViewController.h"

@interface ExamplePagerViewController ()
@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) NSMutableArray *allControllerArray;
@end

@implementation ExamplePagerViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    
    //创建并添加PagerViewController
    _allControllerArray = [NSMutableArray array];
    for (NSInteger i = 0; i < 10; i++) {
        PagerViewController *vc = [PagerViewController new];
        [vc willMoveToParentViewController:self];
        [self addChildViewController:vc];
        [vc didMoveToParentViewController:self];
        [_allControllerArray addObject:vc];
    }
    
    
    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
    flowLayout.itemSize = self.view.bounds.size;
    flowLayout.minimumLineSpacing = 0;
    flowLayout.minimumInteritemSpacing = 0;
    flowLayout.itemSize = CGSizeMake(300, 300);
    flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    CGFloat collectionViewX = (CGRectGetWidth(self.view.frame) - 300) / 2;
    CGFloat collectionViewY = 100;
    CGFloat collectionViewW = 300;
    CGFloat collectionViewH = 300;
    _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(collectionViewX, collectionViewY, collectionViewW, collectionViewH) collectionViewLayout:flowLayout];
    _collectionView.showsHorizontalScrollIndicator = NO;
    _collectionView.pagingEnabled = YES;
    _collectionView.bounces = YES;
    _collectionView.backgroundColor = [UIColor whiteColor];
    _collectionView.dataSource = self;
    [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
    [self.view addSubview:_collectionView];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

#pragma mark -UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    
    return _allControllerArray.count;
    
}

// 将PagerViewController中view添加到UICollectionViewCell中
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    PagerViewController *vc = [_allControllerArray objectAtIndex:indexPath.row];
    vc.view.frame = cell.contentView.frame;
    vc.pageLabel.text = [NSString stringWithFormat:@"第%ld页", indexPath.row];
    [cell.contentView addSubview:vc.view];
    return cell;
    
}

二、PagerViewController

用于在Pager中展示UI,根据外部设置好的frame,做一些布局,这里简单的实现一个随机色,显示页码。
这里要注意外部设置好的frame,需要在viewDidLayoutSubviews中修改PagerViewController上的View的frame,至于为什么要这要做呢?可以复习一下ViewController的生命周期,观察一下frame的变化!

PagerViewController.h文件

创建一个UILabel,来展示当前所处的页码。

#import 
@interface PagerViewController : UIViewController
@property (nonatomic, strong) UILabel *pageLabel;
@end
PagerViewController.m文件

设置一个背景随机色,方便分辨PagerViewController。
加入Tap手势来查看PagerViewController是否可以正常跳转到其他Controller

#import "PagerViewController.h"

@interface PagerViewController ()

@end

@implementation PagerViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.view.backgroundColor = [UIColor randomFlatColor];
    
    _pageLabel = [UILabel new];
    _pageLabel.textAlignment = NSTextAlignmentCenter;
    _pageLabel.font = [UIFont boldSystemFontOfSize:16];
    _pageLabel.textColor = [UIColor whiteColor];
    [self.view addSubview:_pageLabel];
    
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pushViewControllerAction)];
    [self.view addGestureRecognizer:tap];
    
}

- (void)viewDidLayoutSubviews{
    
    _pageLabel.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame));
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

- (void)pushViewControllerAction{
    
    UIViewController *emptyViewController = [UIViewController new];
    emptyViewController.view.backgroundColor = [UIColor whiteColor];
    [self.navigationController pushViewController:emptyViewController animated:YES];
    
}

@end
UICollectionView嵌套UIViewController实现Pager多页滚动_第3张图片

三、实现效果

简单的重用Controller实现了Pager的需求,点击Pager中Controller可以方便的跳转到其他视图。

UICollectionView嵌套UIViewController实现Pager多页滚动_第4张图片
效果

你可能感兴趣的:(UICollectionView嵌套UIViewController实现Pager多页滚动)