写在最开始,前段时间在项目中,需要实现多页水平滚动切换不同页面,如上图所示,weex中官方组件不能满足需求,需要三端(H5、Android、iOS)来实现weex自定义组件pager,通过weex调用<pager>的方法来代用原生的Pager组件。
<pager :src="src" :current="current" @scroll="scroll" @currentChange="currentChange" :style="{ height: listHeight + 'px' }"></pager>
本文只抽离了iOS原生部分实现的内容,主要来说明,在iOS客户端是如何实现这种Pager需求的。
核心思想
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];
一、 ExamplePagerViewController
ExamplePagerViewController.h文件
#import <UIKit/UIKit.h>
@interface ExamplePagerViewController : UIViewController
@end
ExamplePagerViewController.m文件
基于UIKit控件中的UICollectionView,在Cell中嵌套PagerViewController来实现Pager的需求,如下所示:
#import "ExamplePagerViewController.h"
#import "PagerViewController.h"
@interface ExamplePagerViewController ()<UICollectionViewDataSource, UIScrollViewDelegate>
@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 <UIKit/UIKit.h>
@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
三、实现效果
简单的重用Controller实现了Pager的需求,点击Pager中Controller可以方便的跳转到其他视图。