我廠廣招各路大神加入: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