iOS之UICollectionView的使用

一、普通使用

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值