您的位置:首页 > 产品设计 > UI/UE

iOS之UICollectionView的使用

2015-01-07 10:34 323 查看

一、普通使用

1、FKViewController类

//.h
#import <UIKit/UIKit.h>

@interface FKViewController : UIViewController<UICollectionViewDataSource,
UICollectionViewDelegate>
@property (strong, nonatomic) IBOutlet UICollectionView *grid;

@end

//.m
#import <QuartzCore/QuartzCore.h>
#import "FKViewController.h"
#import "FKDetailViewController.h"

@interface FKViewController ()

@end

@implementation FKViewController
NSArray* books;
NSArray* covers;
- (void)viewDidLoad
{
[super viewDidLoad];
// 创建、并初始化NSArray对象。
books = [NSArray arrayWithObjects:@"疯狂Ajax讲义",
@"疯狂Android讲义",
@"疯狂HTML5/CSS3/JavaScript讲义" ,
@"疯狂Java讲义",
@"疯狂Java程序员基本修养",
@"轻量级Java EE企业应用实战",
@"经典Java EE企业应用实战",
@"疯狂XML讲义",
nil];
// 创建、并初始化NSArray对象。
covers = [NSArray arrayWithObjects:@"ajax.png",
@"android.png",
@"html.png" ,
@"java.png",
@"java2.png",
@"javaee.png",
@"javaee2.png",
@"xml.png", nil];
// 为当前导航项设置标题
self.navigationItem.title = @"图书列表";
// 为UICollectionView设置dataSource和delegate
self.grid.dataSource = self;
self.grid.delegate = self;
// 创建UICollectionViewFlowLayout布局对象
UICollectionViewFlowLayout *flowLayout =
[[UICollectionViewFlowLayout alloc] init];
// 设置UICollectionView中各单元格的大小
flowLayout.itemSize = CGSizeMake(120, 160);
// 设置该UICollectionView只支持水平滚动
flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
// 设置各分区上、下、左、右空白的大小。
flowLayout.sectionInset = UIEdgeInsetsMake(0, 2, 0, 0);
// 为UICollectionView设置布局对象
self.grid.collectionViewLayout = flowLayout;
}
// 该方法返回值决定各单元格的控件。
- (UICollectionViewCell *)collectionView:(UICollectionView *)
collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
// 为单元格定义一个静态字符串作为标示符
static NSString* cellId = @"bookCell";  // ①
// 从可重用单元格的队列中取出一个单元格
UICollectionViewCell* cell = [collectionView
dequeueReusableCellWithReuseIdentifier:cellId
forIndexPath:indexPath];
// 设置圆角
cell.layer.cornerRadius = 8;
cell.layer.masksToBounds = YES;
NSInteger rowNo = indexPath.row;
// 通过tag属性获取单元格内的UIImageView控件
UIImageView* iv = (UIImageView*)[cell viewWithTag:1];
// 为单元格内图片控件设置图片
iv.image = [UIImage imageNamed:[covers objectAtIndex:rowNo]];
// 通过tag属性获取单元格内的UILabel控件
UILabel* label = (UILabel*)[cell viewWithTag:2];
// 为单元格内UILabel控件设置文本
label.text = [books objectAtIndex:rowNo];
return cell;
}
// 该方法返回值决定UICollectionView包含多少个单元格
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
{
return books.count;
}
// 当用户单击单元格跳转到下一个视图控制器时激发该方法。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// 获取激发该跳转的单元格
UICollectionViewCell* cell = (UICollectionViewCell*)sender;
// 获取该单元格所在的NSIndexPath
NSIndexPath* indexPath = [self.grid indexPathForCell:cell];
NSInteger rowNo = indexPath.row;
// 获取跳转的目标视图控制器:FKDetailViewController控制器
FKDetailViewController *detailController = segue.destinationViewController;
// 将选中单元格内的数据传给FKDetailViewController控制器对象
detailController.imageName = [covers objectAtIndex:rowNo];
detailController.bookNo = rowNo;
}
@end


1)首先在storyboard上添加一个UINavigationController控件,删除原来的控件。

2)删除UINavigationController的默认UITableViewController的控件,添加UIViewController控件,作为UINavigationController的根视图。UIViewController关联FKViewController类

3)UIViewController添加UILabel和UIImageView控件,设置tag和IBOutlet属性

4)UIViewController添加UICollectionView控件,设置IBOutlet属性

2、FKDetailViewController类

//.h
#import <UIKit/UIKit.h>

@interface FKDetailViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIImageView *bookCover;
@property (strong, nonatomic) IBOutlet UITextView *bookDetail;
// 用于接受上一个控制器传入参数的属性
@property (strong, nonatomic) NSString* imageName;
@property (nonatomic, assign) NSInteger bookNo;
@end

//.m
#import "FKDetailViewController.h"

@implementation FKDetailViewController
NSArray* bookDetails;
- (void)viewDidLoad
{
[super viewDidLoad];
bookDetails = [NSArray arrayWithObjects:
@"长期雄踞各网店Ajax销量排行榜榜首的图书,全面深入介绍了前端开发知识",
@"长期雄踞各网店Andrioid销量排行榜榜首的图书。",
@"重点介绍HTML 5、CSS3、JavaScript等前端开发基础知识" ,
@"Java图书,值得仔细阅读的图书",
@"帮助Java程序员查漏补缺的、突破重点的图书",
@"Java领域3大框架整合开发的图书",
@"以EJB 3为核心的Java EE开发图书",
@"详细介绍有关XML方方面面的图书" ,nil];
}
- (void)viewWillAppear:(BOOL)animated
{
// 设置bookCover控件显示的图片
self.bookCover.image = [UIImage imageNamed:self.imageName];
// 设置bookDetail显示的内容
self.bookDetail.text = [bookDetails objectAtIndex:self.bookNo];
}
@end


1)添加UIViewController,关联到该类

2)添加UILabel和UIImageView到该UIViewController,并设置IBOutlet属性

二、单元格大小不一,添加UICollectionViewDelegateFlowLayout协议

如果单元格的大小不同,则可在.h中添加UICollectionViewDelegateFlowLayout协议,在.m中实现下面方法即可

//.m
- (CGSize)collectionView:(UICollectionView *)collectionView layout:
(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"~~~~~");
// 获取indexPath对应的单元格将要显示的图片
UIImage* image = [UIImage imageNamed:
[covers objectAtIndex:indexPath.row]];
// 控制该单元格的大小为它显示的图片大小的一半
return CGSizeMake(image.size.width / 2
, image.size.height / 2);
}

三、定制UICollectionViewLayout

1、继承UICollectionViewLayout的FKCircleLayout类
//.h
#import <UIKit/UIKit.h>

@interface FKCircleLayout : UICollectionViewLayout
@property (nonatomic, assign) CGPoint center;
@property (nonatomic, assign) CGFloat radius;
@property (nonatomic, assign) NSInteger cellCount;
@end

//.m
#import "FKCircleLayout.h"

#define ITEM_SIZE 72
@implementation FKCircleLayout
// 开始执行的方法
-(void)prepareLayout
{
[super prepareLayout];

CGSize size = self.collectionView.frame.size;
// 计算需要包含多少个单元格
_cellCount = [[self collectionView] numberOfItemsInSection:0];
// 计算环的圆心
_center = CGPointMake(size.width / 2.0, size.height / 2.0);
// 计算环的半径(以宽、高中较小值的2.5分之一作为半径)
_radius = MIN(size.width, size.height) / 2.5;
}
// 该方法的返回值决定UICollectionView所包含控件的大小
-(CGSize)collectionViewContentSize
{
return [self collectionView].frame.size;
}
// 该方法返回的UICollectionViewLayoutAttributes控制指定单元格的大小和位置
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:
(NSIndexPath *)path
{
// 创建一个UICollectionViewLayoutAttributes对象
UICollectionViewLayoutAttributes* attributes =
[UICollectionViewLayoutAttributes
layoutAttributesForCellWithIndexPath:path];
// 设置各单元格的大小
attributes.size = CGSizeMake(ITEM_SIZE, ITEM_SIZE);
// 设置该单元格的中心点坐标,
// 由于程序需要控制各单元格绕城一个圆圈,因此此处使用了三角函数进行计算。
attributes.center = CGPointMake(_center.x + _radius
* cosf(2 * M_PI * path.item / _cellCount),
_center.y + _radius * sinf(2 * M_PI * path.item / _cellCount));
return attributes;
}
// 该方法的返回值控制UICollectionViewLayoutAttributes集合依次控制
// 指定CGRect范围内各单元格的大小和位置
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray* attributes = [NSMutableArray array];
// 将控制每个单元格大小和位置的UICollectionViewLayoutAttributes
// 添加到NSArray中
for (NSInteger i=0 ; i < _cellCount; i++) {
NSIndexPath* indexPath = [NSIndexPath
indexPathForItem:i inSection:0];
[attributes addObject:
[self layoutAttributesForItemAtIndexPath:indexPath]];
}
return attributes;
}
// 每当单元格动态显示时自动调用该方法
- (UICollectionViewLayoutAttributes *)
initialLayoutAttributesForAppearingItemAtIndexPath:
(NSIndexPath *)itemIndexPath
{
UICollectionViewLayoutAttributes* attributes = [self
layoutAttributesForItemAtIndexPath:itemIndexPath];
attributes.alpha = 0.0;
attributes.center = CGPointMake(_center.x, _center.y);
return attributes;
}
// 每当单元格动态消失时自动调用该方法
- (UICollectionViewLayoutAttributes *)
finalLayoutAttributesForDisappearingItemAtIndexPath:
(NSIndexPath *)itemIndexPath
{
UICollectionViewLayoutAttributes* attributes = [self
layoutAttributesForItemAtIndexPath:itemIndexPath];
attributes.alpha = 0.0;
attributes.center = CGPointMake(_center.x, _center.y);
attributes.transform3D = CATransform3DMakeScale(0.1, 0.1, 1.0);
return attributes;
}
@end


2、FKViewController类
//.h
#import <UIKit/UIKit.h>

@interface FKViewController : UIViewController<UICollectionViewDataSource
, UICollectionViewDelegate>
@property (strong, nonatomic) IBOutlet UICollectionView *gridView;
@end

//.m
#import "FKViewController.h"
#import "FKCircleLayout.h"
@interface FKViewController ()

@end

@implementation FKViewController
NSInteger cellCount;
-(void)viewDidLoad
{
// 设置开始的时候包含16个单元格
cellCount = 16;
// 创建自定义的FKCircleLayout布局对象
FKCircleLayout* circleLayout =[[FKCircleLayout alloc] init];
// 设置使用自定义布局对象
self.gridView.collectionViewLayout = circleLayout;
// 设置背景色
self.gridView.backgroundColor = [UIColor grayColor];
// 为UICollectionView设置dataSource和delegate
self.gridView.dataSource = self;
self.gridView.delegate = self;
// 创建一个处理点击的手势处理器
UITapGestureRecognizer* tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(handleTap:)];
// 为UICollectionView增加一个手势处理器
[self.gridView addGestureRecognizer:tapRecognizer];
}
// 该方法的返回值决定该UICollectionView包含多少个单元格
- (NSInteger)collectionView:(UICollectionView *)view
numberOfItemsInSection:(NSInteger)section;
{
return cellCount;
}
// 该方法的返回值决定该UICollectionView指定位置的单元格控件
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
static NSString* cellId = @"cellId";

// 从可重用表格行的队列中取出一个表格行
UICollectionViewCell* cell = [collectionView
dequeueReusableCellWithReuseIdentifier:cellId
forIndexPath:indexPath];
return cell;
}
// 定义处理点击手势的方法
- (void)handleTap:(UITapGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateEnded)
{
// 获取点击点的位置
CGPoint initialPinchPoint = [sender locationInView:self.gridView];
// 获取点击点所在的NSIndexPath(可用于获取被点击的单元格)
NSIndexPath* tappedCellPath = [self.gridView
indexPathForItemAtPoint:initialPinchPoint];
// 如果被点击的单元格存在
if (tappedCellPath)
{
// 减少一个单元格
cellCount --;
// 删除被点击的单元格
[self.gridView deleteItemsAtIndexPaths:
[NSArray arrayWithObject:tappedCellPath]];
}
else
{
// 增加一个单元格
cellCount ++;
// 在UICollectionView的开始处添加一个单元格
[self.gridView insertItemsAtIndexPaths:
[NSArray arrayWithObject:
[NSIndexPath indexPathForItem:0 inSection:0]]];
}
}
}
@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  iOS UICollectionView