1.关于UICollectionView横向滑动分页的问题
首先UICollectionView的布局是由UICollectionViewLayout决定。但使用UICollectionViewFlowLayout设置横向滑动的时候,item会以向下排列的顺序往后排,第二点,collectionView总的滑动范围,由每一个UICollectionViewLayout的itemSize决定,设置contentSize无效,需要通过继承UICollectionViewLayout自定义布局。
CollectViewController.h
@interface CollectViewController : UIViewController<UICollectionViewDataSource,UICollectionViewDelegate> @property(nonatomic,retain)NSMutableArray *dataSource; @property(nonatomic,retain)UICollectionView *myCollectionView;//类似于UITableView
@end
CollectViewController.m
#import "CollectViewController.h" #import "CollectCell.h" #import "CollectLayout.h" @interface CollectViewController () @end @implementation CollectViewController - (void)viewDidLoad { [super viewDidLoad]; UIImageView *bgImageVeiw = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"sharebg"]]; CollectLayout *rac = [[CollectLayout alloc]init]; self.myCollectionView = [[UICollectionView alloc]initWithFrame:self.view.frame collectionViewLayout:rac];//根据位置大小和collectView布局初始化 [self.myCollectionView registerClass:[CollectCell class] forCellWithReuseIdentifier:@"customCell"];//设置cell的类型 self.myCollectionView.delegate = self; self.myCollectionView.dataSource = self; [self.view addSubview:self.myCollectionView]; self.myCollectionView.backgroundView = bgImageVeiw; self.dataSource = [NSMutableArray arrayWithCapacity:30]; for (int i = 1; i <= 20; i++) { NSDictionary *dic = @{@"imageName":[NSString stringWithFormat:@"%d.jpg",i],@"titleName":[NSString stringWithFormat:@"%d",i]}; [self.dataSource addObject:dic]; } } -(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return self.dataSource.count/2;//section的个数 } -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return 2;//每个section有2列 } -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { CollectCell *collectionCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"customCell" forIndexPath:indexPath]; if (!collectionCell) { return nil; } NSString *imageName = [[self.dataSource objectAtIndex:(indexPath.section*2+indexPath.row)] objectForKey:@"imageName"]; NSString *titleName = [[self.dataSource objectAtIndex:(indexPath.section*2+indexPath.row)] objectForKey:@"titleName"]; collectionCell.collectImageView.image = [UIImage imageNamed:imageName]; collectionCell.collectContent.text = titleName; return collectionCell; } @end
CollectLayout.m(作用:对CollectionView布局)
#import "CollectLayout.h" @implementation CollectLayout -(id)init { self = [super init]; if (self) { self.itemSize = CGSizeMake(150, 150); // self.scrollDirection = UICollectionViewScrollDirectionHorizontal; self.sectionInset = UIEdgeInsetsMake(20.0, 0.0, 0.0, 0.0); self.minimumLineSpacing = 50.0; self.minimumInteritemSpacing = 0.0; } return self; } @end
CollectCell.h(类似于UITableCell)
@interface CollectCell : UICollectionViewCell @property(nonatomic,retain)UIImageView *collectImageView; @property(nonatomic,retain)UILabel *collectContent; @end
CollectCell.m
#import "CollectCell.h" @implementation CollectCell - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.frame = CGRectMake(0, 0, 150, 150); UIImageView *bgImageView =[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"BookShelfCell"]]; bgImageView.frame = CGRectMake(0, 0,150,150); [self.contentView addSubview:bgImageView]; self.collectImageView = [[UIImageView alloc]initWithFrame:CGRectMake(25,10, 100, 100)]; [self.contentView addSubview:self.collectImageView]; self.collectContent = [[UILabel alloc]initWithFrame:CGRectMake(0, 110,150,30)]; self.collectContent.textAlignment = NSTextAlignmentCenter; [self.contentView addSubview:self.collectContent]; } return self; } @end
part2
#import "ViewController.h" @interface JSCollectionViewCell : UICollectionViewCell @property(nonatomic,strong)UILabel *textLabel; @property(nonatomic,strong)UIImageView *accessoryView; -(void)removeAccessoryImageView; @end @implementation JSCollectionViewCell -(instancetype)initWithFrame:(CGRect)frame{ if (self=[super initWithFrame:frame]) { _textLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; _textLabel.textAlignment = NSTextAlignmentCenter; [self addSubview:_textLabel]; } return self; } -(void)removeAccessoryImageView{ if (_accessoryView) { [_accessoryView removeFromSuperview]; } } -(void)setAccessoryView:(UIImageView *)accessoryView{ [self removeFromSuperview];//清理图片缓冲 _accessoryView = accessoryView; _accessoryView.frame = CGRectMake(self.frame.size.width-10-16, (self.frame.size.height-12)/2, 16, 12);//离父视图10个像素,13 [self addSubview:_accessoryView]; } @end //////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// @interface ViewController ()<UICollectionViewDataSource,UICollectionViewDelegate> @property(nonatomic,retain)UICollectionView *collectionView; @property(nonatomic,retain)NSMutableArray *data; @property(nonatomic,retain)NSString *currentTitle; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self p_initUI]; _data = [NSMutableArray arrayWithObjects:@"不限人数", @"单人餐", @"双人餐", @"3~4人餐", @"不限人数2", @"单人餐2", @"双人餐2", @"3~4人餐2",@"不限人数3", @"单人餐3", @"双人餐3", @"3~4人餐3",nil]; } -(void)p_initUI{ UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init]; flowLayout.minimumInteritemSpacing = 0; _collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 65, 320,200) collectionViewLayout:flowLayout]; [_collectionView registerClass:[JSCollectionViewCell class] forCellWithReuseIdentifier:@"CollectionCell"]; _collectionView.backgroundColor = [UIColor groupTableViewBackgroundColor]; _collectionView.dataSource = self; _collectionView.delegate = self; [self.view addSubview:_collectionView]; } #pragma mark --UICollectionViewDataSource -(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{ return 1; } -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return _data.count; } -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ static NSString *collectIdentitfer = @"CollectionCell"; JSCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:collectIdentitfer forIndexPath:indexPath]; cell.textLabel.text = [_data objectAtIndex:indexPath.row]; cell.backgroundColor = [UIColor whiteColor]; cell.textLabel.font = [UIFont systemFontOfSize:14]; if ([self.currentTitle isEqualToString:cell.textLabel.text]) { cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ico_make"]]; }else{ [cell removeAccessoryImageView]; } return cell; } #pragma mark --UICollectionViewDelegateFlowLayout - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { return CGSizeMake((collectionView.frame.size.width-1)/2, 38);//想要设置单独定义某个Cell的尺寸(collectionView.frame.size.width-1)/2 } -(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { return UIEdgeInsetsMake(0, 0, 1,0.5);//设置cell边框空隙 } #pragma mark --UICollectionViewDelegate -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"titles = %@",[_data objectAtIndex:indexPath.item]); self.currentTitle = [_data objectAtIndex:indexPath.item]; [_collectionView reloadData]; } - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{ return 0.5;//设定全局的行间距,如果想要设定指定区内Cell的最小行距 } @end
3.添加区间头,区间头需要是UICollectionReusableView的子类
[_collectionView registerClass:[CollectionHeadView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"setionHead"];
.
-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{ if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { CollectionHeadView *headView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"setionHead" forIndexPath:indexPath]; if (headView==nil) { headView =[[CollectionHeadView alloc]initWithFrame:CGRectMake(0, 0,CGRectGetWidth(self.frame), 40)]; } return headView; }else if ([kind isEqualToString:UICollectionElementKindSectionFooter]) { return nil; } return nil; } -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{ return CGSizeMake(CGRectGetWidth(self.frame), 40); }
4.对UICollectionView自定义布局,继承UICollectionViewLayout,重载一些方法
1.-(void)prepareLayout 准备布局方法,初始化一些布局用的参数。
2.-(CGSize)collectionViewContentSize 设置显示范围,是否支持滚动和滚动方向在该方法设置。
3.-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect 设置多少个UICollectionViewLayoutAttributes。通过N个indexPath返回的是包含UICollectionViewLayoutAttributes的NSArray,UICollectionViewLayoutAttributes可以是cell、背景图、区间头尾信息。通过不同的初始化方法可以得到不同类型的:
layoutAttributesForCellWithIndexPath:
layoutAttributesForSupplementaryViewOfKind:withIndexPath:
layoutAttributesForDecorationViewOfKind:withIndexPath:
4.-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath _)indexPath 设置cell的布局
5.-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds 当边界发生改变时,是否应该刷新布局
例子:添加背景装饰
#import "CustomLayout.h" #import "CollectionDecorationView.h" @implementation CustomLayout - (void)prepareLayout{ [super prepareLayout]; //注册装饰CollectionDecorationView,继承UICollectionReusableView [self registerClass:[CollectionDecorationView class] forDecorationViewOfKind:@"CDV"]; } //设置显示范围 -(CGSize)collectionViewContentSize{ return self.collectionView.frame.size; } //设置多少个背景装饰 -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{ NSMutableArray* attributes = [NSMutableArray array]; //把Decoration View的布局加入可见区域布局。 NSIndexPath* indexPath = [NSIndexPath indexPathForItem:0 inSection:0]; [attributes addObject:[self layoutAttributesForDecorationViewOfKind:@"CDV"atIndexPath:indexPath]]; return attributes; } //设置背景装饰的布局 -(UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath{ UICollectionViewLayoutAttributes *att = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:elementKind withIndexPath:indexPath]; att.frame = self.collectionView.frame; return att; } @end