UICollectionView

引用自:http://www.lxweimin.com/p/c59a5c92f859

一、UICollectionVIew基礎

第一步:創(chuàng)建布局對象:

如果使用系統(tǒng)的布局類,我們通常是使用其UICollectionViewFlowLayout子類,通過這個子類來創(chuàng)建我們的布局對象。實例:UICollectionVIewFlowLayout *flowLayout = [UICollectionVIewFlowLayout new];

通過這個實例化的對象提供了一些基本的屬性,用于幫助我們控制布局的方式,當然這個類也有其自身的協(xié)議,通過簽署協(xié)議可以實現(xiàn)協(xié)議中的一些方法,這些方法可以幫助我們實現(xiàn)更加完善的布局。協(xié)議名字叫做:“UICollectionVIewDelegateFlowLayout”,這個協(xié)議也是實現(xiàn)基本CollectionVIew的三個協(xié)議中必須用到的,其他另外兩個協(xié)議分別是:UICollectionViewDataSource(數(shù)據(jù)源)、UICollectionViewDelegate。

下面簡單介紹一些關于這個類對象用于實現(xiàn)布局的屬性有哪些:

@property(nonatomic)CGFloatminimumLineSpacing;// 這個用于指定每個Item的行間距,默認間距是10.

@property(nonatomic)CGFloatminimumInteritemSpacing;//用于指定每個單元的列間距。

@property(nonatomic)CGSizeitemSize;//指定每個cell的size.

@property(nonatomic)CGSizeestimatedItemSizeNS_AVAILABLE_IOS(8_0);//defaults to CGSizeZero - setting a non-zero size enables cells that self-size via -preferredLayoutAttributesFittingAttributes:

@property(nonatomic)UICollectionViewScrollDirectionscrollDirection;// default is UICollectionViewScrollDirectionVertical

@property(nonatomic)CGSizeheaderReferenceSize;

@property(nonatomic)CGSizefooterReferenceSize;//頭部增添視圖的size

@property(nonatomic)UIEdgeInsetssectionInset;//設置分區(qū)的內邊距距離上左下右的距離,所以這個參數(shù)有四個參數(shù)。

// Set these properties to YES to get headers that pin to the top of the screen and footers that pin to the bottom while scrolling (similar to UITableView).

@property(nonatomic)BOOLsectionHeadersPinToVisibleBoundsNS_AVAILABLE_IOS(9_0);

@property(nonatomic)BOOLsectionFootersPinToVisibleBoundsNS_AVAILABLE_IOS(9_0);c//用于控制是否在當前窗口顯示下一個分區(qū)的尾增添

第二步:通過布局對象創(chuàng)建UICollectionView,并設置相關屬性,重點是給代理屬性給定對象。

初始化UICollectionVIew的方法:

Frame:指定UICollectionView的Frame

collectionViewLayout:指定UICollectView的布局對象。

- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout*)layoutNS_DESIGNATED_INITIALIZER;

第三步:設置好各個重用標識

這里就不多說了,在代碼的全局位置指定三個全局字符常量。

第四步:使用重用標識注冊相關的重用池。

cell的重用池的注冊方法:

Class:指定用哪個類作為cell,所以我們可以通過新建繼承自UICollectionViewLayout的類來自定義cell.

- (void)registerClass:(nullableClass)cellClass forCellWithReuseIdentifier:(NSString*)identifier;

補充視圖重用池的注冊方法:

forSupplementaryViewOfKind:指定補充視圖的類型

withReuseIdentifier:指定一個重用標識符

- (void)registerClass:(nullableClass)viewClass forSupplementaryViewOfKind:(NSString*)elementKind withReuseIdentifier:(NSString*)identifier;

第五步:實現(xiàn)UICollectionViewDataSource的幾個代理方法(這里只提幾個常用的)

#pragma?mark?----?UICollectionViewDataSource

// ?指定在一個CollectionView上分區(qū)的數(shù)量。

-?(NSInteger)numberOfSectionsInCollectionView:(UICollectionView?*)collectionView

{

return?1;

}

// 指定在每個分區(qū)上Item的數(shù)量。

-?(NSInteger)collectionView:(UICollectionView?*)collectionView?numberOfItemsInSection:(NSInteger)section

{

return?_section0Array.count;

}

// 從重用池中取出UICollectionVIew的celle來給每個Item賦值。

-?(UICollectionViewCell?*)collectionView:(UICollectionView?*)collectionView?cellForItemAtIndexPath:(NSIndexPath?*)indexPath

{

UICollectionViewCell?*cell?=?[_collectionView?dequeueReusableCellWithReuseIdentifier:cellId?forIndexPath:indexPath];

cell.backgroundColor?=?[UIColor?purpleColor];

return?cell;

}

//?和UITableView類似,UICollectionView也可設置段頭段尾

這個方法中的參數(shù)分別是:

collectionView:這個就不解釋了,每個協(xié)議中必須傳入的跟類。

viewForSupplementaryElementOfKind:根據(jù)傳入的Kind值來判斷到底添加的是那種類型的視圖。

atIndexPath:這個參數(shù)通過傳值來確定到底給那個分區(qū)補充視圖。

-?(UICollectionReusableView?*)collectionView:(UICollectionView?*)collectionView?viewForSupplementaryElementOfKind:(NSString?*)kind?atIndexPath:(NSIndexPath?*)indexPath

{

if([kind?isEqualToString:UICollectionElementKindSectionHeader])

{

UICollectionReusableView?*headerView?=?[_collectionView?dequeueReusableSupplementaryViewOfKind:kind?withReuseIdentifier:headerId?forIndexPath:indexPath];

if(headerView?==?nil)

{

headerView?=?[[UICollectionReusableView?alloc]?init];

}

headerView.backgroundColor?=?[UIColor?grayColor];

return?headerView;

}

else?if([kind?isEqualToString:UICollectionElementKindSectionFooter])

{

UICollectionReusableView?*footerView?=?[_collectionView?dequeueReusableSupplementaryViewOfKind:kind?withReuseIdentifier:footerId?forIndexPath:indexPath];

if(footerView?==?nil)

{

footerView?=?[[UICollectionReusableView?alloc]?init];

}

footerView.backgroundColor?=?[UIColor?lightGrayColor];

return?footerView;

}

return?nil;

}

// 暫時理解為:能夠移動的Item,有待驗證。

-?(BOOL)collectionView:(UICollectionView?*)collectionView?canMoveItemAtIndexPath:(NSIndexPath?*)indexPath

{

return?YES;

}

// ?暫時理解為:給能夠移動的Item指定移動路徑,有待驗證。

moveItemAtIndexPath:能夠一定的Item路徑。

toIndexPath:移動到的目標路徑。

-?(void)collectionView:(UICollectionView?*)collectionView?moveItemAtIndexPath:(NSIndexPath?*)sourceIndexPath?toIndexPath:(NSIndexPath*)destinationIndexPath

{

}

第六步:實現(xiàn)UICollectionViewDelegateFlowLayout協(xié)議方法(這里的很多方法用屬性的點語法同樣可以實現(xiàn),建議使用點語法。)

-?(CGSize)collectionView:(UICollectionView?*)collectionView?layout:(UICollectionViewLayout*)collectionViewLayout?sizeForItemAtIndexPath:(NSIndexPath?*)indexPath

{

return?(CGSize){cellWidth,cellWidth};

}

-?(UIEdgeInsets)collectionView:(UICollectionView?*)collectionView?layout:(UICollectionViewLayout*)collectionViewLayout?insetForSectionAtIndex:(NSInteger)section

{

return?UIEdgeInsetsMake(5,?5,?5,?5);

}

-?(CGFloat)collectionView:(UICollectionView?*)collectionView?layout:(UICollectionViewLayout*)collectionViewLayout?minimumLineSpacingForSectionAtIndex:(NSInteger)section

{

return?5.f;

}

-?(CGFloat)collectionView:(UICollectionView?*)collectionView?layout:(UICollectionViewLayout*)collectionViewLayout?minimumInteritemSpacingForSectionAtIndex:(NSInteger)section

{

return?5.f;

}

-?(CGSize)collectionView:(UICollectionView?*)collectionView?layout:(UICollectionViewLayout*)collectionViewLayout?referenceSizeForHeaderInSection:(NSInteger)section

{

return?(CGSize){ScreenWidth,44};

}

-?(CGSize)collectionView:(UICollectionView?*)collectionView?layout:(UICollectionViewLayout*)collectionViewLayout?referenceSizeForFooterInSection:(NSInteger)section

{

return?(CGSize){ScreenWidth,22};

}

第七步:實現(xiàn)UICollectionViewDelegate方法

// 指定那些Item需要高亮顯示

-?(BOOL)collectionView:(UICollectionView?*)collectionView?shouldHighlightItemAtIndexPath:(NSIndexPath?*)indexPath

{

return?YES;

}

//?點擊高亮

-?(void)collectionView:(UICollectionView?*)collectionView?didHighlightItemAtIndexPath:(NSIndexPath?*)indexPath

{

UICollectionViewCell?*cell?=?[collectionView?cellForItemAtIndexPath:indexPath];

cell.backgroundColor?=?[UIColor?greenColor];

}

//?選中某item

-?(void)collectionView:(UICollectionView?*)collectionView?didSelectItemAtIndexPath:(NSIndexPath?*)indexPath

{

}

//?長按某item,彈出copy和paste的菜單

-?(BOOL)collectionView:(UICollectionView?*)collectionView?shouldShowMenuForItemAtIndexPath:(NSIndexPath?*)indexPath

{

return?YES;

}

//?使copy和paste有效

-?(BOOL)collectionView:(UICollectionView?*)collectionView?canPerformAction:(SEL)action?forItemAtIndexPath:(NSIndexPath?*)indexPath?withSender:(nullable?id)sender

{

if?([NSStringFromSelector(action)?isEqualToString:@"copy:"]?||?[NSStringFromSelector(action)?isEqualToString:@"paste:"])

{

return?YES;

}

return?NO;

}

//

-?(void)collectionView:(UICollectionView?*)collectionView?performAction:(SEL)action?forItemAtIndexPath:(NSIndexPath?*)indexPath?withSender:(nullable?id)sender

{

if([NSStringFromSelector(action)?isEqualToString:@"copy:"])

{

//? ? ? ? NSLog(@"-------------執(zhí)行拷貝-------------");

[_collectionView?performBatchUpdates:^{

[_section0Array?removeObjectAtIndex:indexPath.row];

[_collectionView?deleteItemsAtIndexPaths:@[indexPath]];

}?completion:nil];

}

else?if([NSStringFromSelector(action)?isEqualToString:@"paste:"])

{

NSLog(@"-------------執(zhí)行粘貼-------------");

}

}

二、自定義布局

UICollectionView自定義布局

要自定義UICollectionView布局,就要子類化UICollectionViewLayout,然后重寫它的一些方法以達到我們自定義布局的需求。下來我們來看看UICollectionViewLayout類里一些比較重要的方法:

- (void)prepareLayout;為layout顯示做準備工作,你可以在該方法里設置一些屬性。

- (CGSize)collectionViewContentSize;返回layout的size。

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect;返回在collectionView的可見范圍內(bounds)所有item對應的layoutAttrure對象裝成的數(shù)組。collectionView的每個item都對應一個專門的UICollectionViewLayoutAttributes類型的對象來表示該item的一些屬性,比如bounds,size,transform,alpha等。

- (UICollectionViewLayoutAttributes)layoutAttributesForItemAtIndexPath:(NSIndexPath)indexPath;傳入indexPath,返回該indexPath對應的layoutAtture對象。

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;當當前l(fā)ayout的布局發(fā)生變動時,是否重寫加載該layout。默認返回NO,若返回YES,則重新執(zhí)行這倆方法:

- (void)prepareLayout;

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect;

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity;返回layout“最終”的偏移量,何謂“最終”,手指離開屏幕時layout的偏移量不是最終的,因為它有慣性,當它停止時才是“最終”偏移量。

自定義插入刪除動畫

插入刪除的操作

添加在哪觸發(fā):

UIBarButtonItem?*btnItem?=?[[UIBarButtonItem?alloc]?initWithTitle:@"添加"

style:UIBarButtonItemStylePlain

target:self

action:@selector(addItemBtnClick:)];

self.navigationItem.rightBarButtonItem?=?btnItem;

添加的實現(xiàn):

//?添加(插入item)

-?(void)addItemBtnClick:(UIBarButtonItem?*)btnItem

{

[_collectionView?performBatchUpdates:^{

//?構造一個indexPath

NSIndexPath?*indePath?=?[NSIndexPath?indexPathForItem:_section0Array.count?inSection:0];

[_collectionView?insertItemsAtIndexPaths:@[indePath]];?//?然后在此indexPath處插入給collectionView插入一個item

[_section0Array?addObject:@"x"];?//?保持collectionView的item和數(shù)據(jù)源一致

}?completion:nil];

}

因為是練習Demo,所以暫時把刪除的觸發(fā)源寫在了長按某Item彈出菜單的copy按鈕里。實際中你可以自定義UICollectionViewCell,添加長按手勢,長按抖動出現(xiàn)叉號,然后刪除等,隨你怎么做。

//?copy?and?paste?的實現(xiàn)

-?(void)collectionView:(UICollectionView?*)collectionView?performAction:(SEL)action?forItemAtIndexPath:(NSIndexPath?*)indexPath?withSender:(nullable?id)sender

{

if([NSStringFromSelector(action)?isEqualToString:@"copy:"])

{

//? ? ? ? NSLog(@"-------------執(zhí)行拷貝-------------");

[_collectionView?performBatchUpdates:^{

[_section0Array?removeObjectAtIndex:indexPath.row];

[_collectionView?deleteItemsAtIndexPaths:@[indexPath]];

}?completion:nil];

}

else?if([NSStringFromSelector(action)?isEqualToString:@"paste:"])

{

NSLog(@"-------------執(zhí)行粘貼-------------");

}

}

自定義轉場動畫

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容