我厂广招各路大神加入:job.koudaitong.com
可以发简历到 tianchi@qima-inc.com O(∩_∩)O~
接下来就是主要的CollectionView的实现。首先是头文件的实现,先定义一个用来区分Collection状态的枚举:
#import <UIKit/UIKit.h>
typedef enum {
CS_Init,
CS_More,
CS_Refresh
}CollectionState;
然后定义delegate与DataSource:
@class iCollectionItem;
@protocol iCollectionDataSource;
@protocol iCollectionDelegate;
定义CollectionView:
@interface iCollectionView : UIScrollView<UIScrollViewDelegate>
@property (weak, nonatomic) id<iCollectionDataSource> dataSource;
@property (weak, nonatomic) id<iCollectionDelegate> customDelegate;
-(iCollectionItem *)dequeueReusableItemWithIdentifier:(NSString *)identifier;
-(void)addItemsIntoDic;//废弃不用
-(void)itemClickedAtPoint:(CGPoint)point;
-(void)reloadData;
-(iCollectionItem *)getItemAtPoint:(CGPoint)point;
@property (strong,nonatomic) UIView *headerView;
@end
itemClickedAtPoint:方法用来响应item的点击手势,reloadData方法用来重新加载CollectionView,getItemAtPoint:方法用来根据point获取item对象。然后是两个委托(delegate,datasource)的详细定义:
#pragma mark -
#pragma mark 委托
@protocol iCollectionDataSource<NSObject>
@required
-(NSInteger)numberOfItemsInCollection;
-(NSInteger)numberOfItemsInRow;
@optional
-(NSInteger)numberofMore;
@end
@protocol iCollectionDelegate<NSObject>
@required
-(iCollectionItem *)itemInCollectionAtPoint:(CGPoint)point collectionView:(iCollectionView *)collection;
-(CGSize)itemSizeInCollection;//item的大小
@optional
-(void)itemDidSelectedAtPoint:(CGPoint)point;//item的点击响应事件
-(BOOL)isNeedRefreshOrMore;//是否需要添加刷新、更多
-(void)doCollectionRefresh;//执行刷新事件
-(void)doCollectionMore;//执行更多加载事件
-(UIView *)collectionViewForHeader;//headerView
-(CGFloat)spliteWidth;//item之间的分隔距离
-(CGFloat)marginsLength;//item的边距
@end
接下来是.m中的具体实现,首先引入头文件:
#import "iCollectionView.h"
#import "iCollectionItem.h"
#import "BaseRMView.h"//刷新、更多
然后定义一些“私有”变量:
@interface iCollectionView()
@property (strong, nonatomic) NSMutableDictionary *contentItemDictionary;/*cache*/
@property (assign,nonatomic) NSInteger showCount;
@property (assign,nonatomic) NSInteger offRowIndex;
@property (assign,nonatomic) CGFloat itemSpliteWidth;
@property (assign,nonatomic) NSInteger rows;
@property (assign, nonatomic) NSInteger numberOfItemsInCollection;
@property (assign,nonatomic) NSInteger numberOfItemsInRow;
@property (assign, nonatomic) CGFloat heightOfRow;
@property (assign, nonatomic) CGRect viewFrame;
@property (assign,nonatomic) BOOL isFirstLoad;
@property (assign,nonatomic) CGFloat lastOffsetY;
@property (assign,nonatomic) NSInteger lastRowIndex;
@property (assign,nonatomic) NSInteger topRowIndex;
@property (assign,nonatomic) NSInteger numberOfMore;
@property (assign,nonatomic) BOOL isNeedShowMoreTag;
@property (strong,nonatomic) BaseRMView *refreshView;
@property (strong,nonatomic) BaseRMView *moreView;
@property (assign,nonatomic) CGFloat baseOffsetY;
@property (assign,nonatomic) CGFloat baseCanMove;
@property (assign,nonatomic) NSInteger beforeRowCount;
@property (assign,nonatomic) CGSize itemSize;
@property (assign,nonatomic) CGFloat marginsLength;
//@property (assign,nonatomic) NSInteger firstShowCount;
@end
然后是页面的初始化:
#pragma mark -
#pragma mark 页面初始化
-(id)init{
CGRect frame=[UIScreen mainScreen].applicationFrame;
self=[self initWithFrame:frame];
if(self){
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_viewFrame=frame;
self.delegate=self;
_isFirstLoad=YES;
_contentItemDictionary=[[NSMutableDictionary alloc] init];
_isNeedShowMoreTag=NO;
}
return self;
}
然后是数据的初始化:
#pragma mark -
#pragma mark 数据初始化
-(void)loadData{
if ([_dataSource respondsToSelector:@selector(numberOfItemsInCollection)]) {
_numberOfItemsInCollection=[_dataSource numberOfItemsInCollection];
}else{
_numberOfItemsInCollection=0;
}
if([_dataSource respondsToSelector:@selector(numberOfItemsInRow)]){
_numberOfItemsInRow=[_dataSource numberOfItemsInRow];
_heightOfRow=((320-10-10-(_numberOfItemsInRow-1)*10)/_numberOfItemsInRow);
_itemSpliteWidth=10;
}else{
_numberOfItemsInRow=3;//默认为3
_heightOfRow=88;
_itemSpliteWidth=18;
}
if ([_dataSource respondsToSelector:@selector(numberofMore)]) {
_numberOfMore=[_dataSource numberofMore];
}
if ([_customDelegate respondsToSelector:@selector(isNeedRefreshOrMore)]) {
_isNeedShowMoreTag=[_customDelegate isNeedRefreshOrMore];
}
if ([_customDelegate respondsToSelector:@selector(collectionViewForHeader)]) {
_headerView=[_customDelegate collectionViewForHeader];
if (![self.subviews containsObject:_headerView]) {
[self addSubview:_headerView];
}
}
if ([_customDelegate respondsToSelector:@selector(itemSizeInCollection)]) {
CGSize itemSize=[_customDelegate itemSizeInCollection];
_itemSize=itemSize;
}
if ([_customDelegate respondsToSelector:@selector(spliteWidth)]) {
_itemSpliteWidth=[_customDelegate spliteWidth];
}else{
_itemSpliteWidth=10;
}
if ([_customDelegate respondsToSelector:@selector(marginsLength)]) {
_marginsLength=[_customDelegate marginsLength];
}else{
_marginsLength=10;
}
_rows=ceil((float)_numberOfItemsInCollection/_numberOfItemsInRow);
CGFloat contentHeight=(_rows*_itemSize.height + (_rows+1)*_itemSpliteWidth+_headerView.frame.size.height);
CGFloat scrollContentHeight=contentHeight>_viewFrame.size.height?
contentHeight : _viewFrame.size.height;
[self setContentSize:CGSizeMake(_viewFrame.size.width, scrollContentHeight)];
_showCount= (NSInteger)ceil((self.frame.size.height/(_itemSize.height +10)));
if (_rows!=0) {
if (self.contentOffset.y<_headerView.frame.size.height) {
_topRowIndex=0;
CGFloat offSetY=self.contentOffset.y<0?0:self.contentOffset.y;
_lastRowIndex=(_viewFrame.size.height-_headerView.frame.size.height+offSetY)/(_itemSize.height +_itemSpliteWidth);
}else{
_topRowIndex=(self.contentOffset.y-_headerView.frame.size.height)/(_itemSize.height +_itemSpliteWidth);
_lastRowIndex=(_viewFrame.size.height-_headerView.frame.size.height+self.contentOffset.y)/(_itemSize.height +_itemSpliteWidth);
}
for (int i=_topRowIndex; i<_lastRowIndex+1; i++) {
[self creatItem:i];
}
}else{
for (UIView *subView in self.subviews) {
[subView removeFromSuperview];
}
}
if (_isNeedShowMoreTag==YES) {
if (![self.subviews containsObject:_refreshView]) {
_refreshView=[[BaseRMView alloc] initWithState:Refresh];
[_refreshView setFrame:CGRectMake(0, -50, 320, 50)];
[_refreshView setBackgroundColor:[UIColor grayColor]];
[self addSubview:_refreshView];
}
if (![self.subviews containsObject:_moreView]) {
_moreView=[[BaseRMView alloc] initWithState:More];
[_moreView setFrame:CGRectMake(0, self.contentSize.height, 320, 50)];
[_moreView setBackgroundColor:[UIColor grayColor]];
[self addSubview:_moreView];
}else{
[_moreView setFrame:CGRectMake(0, self.contentSize.height, 320, 50)];
}
}
}
在这里我们获取了item的个数、每一行中item的个数、每一个item的大小、item之间的分隔距离、item的边距,以及计算除了总行数、view中能够现实的item行数(showCount)、设置了ScrollView的滚动大小(contentSize、初始化了topIndex(当前显示的最上一行index)与lastIndex(当前显示的最下一行index),在最后初始化了刷新与加载的view。