UICollectionView

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

一唠帝、UICollectionVIew基礎(chǔ)

第一步:創(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。

下面簡單介紹一些關(guān)于這個類對象用于實現(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ū)的內(nèi)邊距距離上左下右的距離,所以這個參數(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,并設置相關(guān)屬性蔫仙,重點是給代理屬性給定對象。

初始化UICollectionVIew的方法:

Frame:指定UICollectionView的Frame

collectionViewLayout:指定UICollectView的布局對象丐箩。

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

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

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

第四步:使用重用標識注冊相關(guān)的重用池屎勘。

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的可見范圍內(nèi)(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:^{

//?構(gòu)造一個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í)行粘貼-------------");

}

}

自定義轉(zhuǎn)場動畫

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末庐杨,一起剝皮案震驚了整個濱河市选调,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌灵份,老刑警劉巖仁堪,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異填渠,居然都是意外死亡弦聂,警方通過查閱死者的電腦和手機鸟辅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來莺葫,“玉大人匪凉,你說我怎么就攤上這事∞嗝剩” “怎么了再层?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長堡纬。 經(jīng)常有香客問我聂受,道長,這世上最難降的妖魔是什么烤镐? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任饺饭,我火速辦了婚禮,結(jié)果婚禮上职车,老公的妹妹穿的比我還像新娘瘫俊。我一直安慰自己,他們只是感情好悴灵,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布扛芽。 她就那樣靜靜地躺著,像睡著了一般积瞒。 火紅的嫁衣襯著肌膚如雪川尖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天茫孔,我揣著相機與錄音叮喳,去河邊找鬼。 笑死缰贝,一個胖子當著我的面吹牛馍悟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播剩晴,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼锣咒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了赞弥?” 一聲冷哼從身側(cè)響起毅整,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绽左,沒想到半個月后悼嫉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡拼窥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年戏蔑,在試婚紗的時候發(fā)現(xiàn)自己被綠了蹋凝。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡辛臊,死狀恐怖仙粱,靈堂內(nèi)的尸體忽然破棺而出房交,到底是詐尸還是另有隱情彻舰,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布候味,位于F島的核電站刃唤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏白群。R本人自食惡果不足惜尚胞,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帜慢。 院中可真熱鬧笼裳,春花似錦、人聲如沸粱玲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抽减。三九已至允青,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卵沉,已是汗流浹背颠锉。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留史汗,地道東北人琼掠。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像停撞,于是被迫代替她去往敵國和親眉枕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容