我厂广招各路大神加入:job.koudaitong.com
能够发简历到 tianchi@qima-inc.com O(∩_∩)O~app
接下来就是主要的CollectionView的实现。首先是头文件的实现,先定义一个用来区分Collection状态的枚举:ide
#import <UIKit/UIKit.h> typedef enum { CS_Init, CS_More, CS_Refresh }CollectionState;
而后定义delegate与DataSource:ui
@class iCollectionItem; @protocol iCollectionDataSource; @protocol iCollectionDelegate;
定义CollectionView:atom
@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)的详细定义:code
#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
而后是页面的初始化:rem
#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; }
而后是数据的初始化:get
#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。it