自定義UICollectionViewCell 以及碰到的問題

自定義UICollectionViewCell 以及碰到的問題
原創 2016年09月12日 16:37:50 標簽:UICollectionView /自定義UIControllViewCel /ios 10024
前言:

今天沒事自己寫了個UICollectionView也就是九宮格的demo ,遇到幾個小問題,雖然都很快解決了,但是這里還是把它記錄下來,以后方便查閱。
(UICollectionView 一下用九宮格代稱)廢話不多說了,直接開始。微笑
創建一個UICollectionView

首先,創建一個UICollectionView ,需要設置的幾個代理 UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout。九宮格 跟UITableView類似,這里只是實現最簡單的代理方法。
[objc] view plain copy

  • (UICollectionView *)collectionView
    {
    if (_collectionView == nil) {

      UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];  
    
      _collectionView = [[UICollectionView alloc]initWithFrame:self.view.frame collectionViewLayout:flowLayout];  
      _collectionView.delegate = self;  
      _collectionView.dataSource = self;  
      [_collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:CellIdentifier];  
        
      _collectionView.backgroundColor = [UIColor grayColor];  
    

    }

    return _collectionView;
    }

其中_collectionView 是我創建的九宮格,CollectionViewCell 是我創建的自定義Cell,這個下面再講。
上面我就碰到了了一個小問題,其實也是我自己不細心的原因,但是也是容易出錯的地方:
[objc] view plain copy
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];

_collectionView = [[UICollectionView alloc]initWithFrame:self.view.frame collectionViewLayout:flowLayout];
上面的UICollectionViewFlowLayout ,這個類是九宮格用來實現自動布局的,注意千萬不要寫錯,我就因為寫錯,寫成了
UICollectionViewLayout (這個類我是直接點擊去九宮格的初始化方法里面看到的)導致了九宮格顯示不出來,其他地方也沒有錯,
調了好幾遍,最后終于發現是這個類寫錯了,UICollectionViewFlowLayout 是UICollectionViewLayout 的子類。
好了,一個問題過去了。
準備UICollectionView 的數據

在實現九宮格的代理方法之前,先展示一下 需要的數據
[objc] view plain copy
@property (nonatomic, copy) NSMutableArray *dataSourceArray;
//宏是完全替換

define CellWidthSpace 20

define CellWidth (kScreenWidth - (5 * CellWidthSpace))/4

define CellLineSpace 10

self.dataSourceArray = [NSMutableArray arrayWithArray:@[@"image1.png",@"image2.png",@"image3.png",<span style="font-family: Arial, Helvetica, sans-serif;">@"image4.png",@"image5.png",@"image4.png",@"image3.png",@"image2.png",@"image1.png"]];</span>
dataSourceArray 是九宮格的數據,CellWidthSpace 是每行Cell之間的間距,CellLineSpace 是每列Cell之間的間距,這個
都是自己定義的。 kScreenWidth 是整個屏幕的寬度,重點是CellWidth, 我要顯示4列的九宮格,間距需要5個,所以就是 屏寬度
減去5個空隙 后再除以4.就得到了每個Cell的 的寬度。
實現UICollectionView的代理

[objc] view plain copy

pragma mark UICollectionViewDelegateFlowLayout

//設置每個Cell 的寬高

  • (CGSize)collectionView:(UICollectionView *)collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
    {
    return CGSizeMake(CellWidth, CellWidth);<span style="white-space:pre"> </span>
    }
    //設置Cell 之間的間距 (上,左,下,右)
  • (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
    {
    return UIEdgeInsetsMake(CellLineSpace, CellWidthSpace, CellLineSpace, CellWidthSpace);
    }

pragma mark UICollectionViewDataSource

//設置九宮格Cell 的個數

  • (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
    {
    return self.dataSourceArray.count;
    }
    //設置Cell

  • (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
    CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
    cell.imageName = self.dataSourceArray[indexPath.row];
    cell.backgroundColor = [UIColor whiteColor];

    return cell;
    }

pragma mark UICollectionViewDelegate

//設置點擊 Cell的點擊事件

  • (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
    {
    [collectionView deselectItemAtIndexPath:indexPath animated:YES];//取消選中

    [self alertView:[NSString stringWithFormat:@"點擊的是%ld",indexPath.row]];
    }
    //這個不是必須的方法 是Cell 將要顯示

  • (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
    {
    cell.layer.transform = CATransform3DMakeScale(0.3, 0.3, 1);//縮放比例
    [UIView animateWithDuration:0.8 animations:^{
    cell.layer.transform = CATransform3DMakeScale(1, 1, 1);//還原為1
    }];<span style="white-space:pre"> </span> <span style="font-family: Arial, Helvetica, sans-serif;">}</span>
    [objc] view plain copy

pragma mark UIAlertView

  • (void)alertView:(NSString *)message
    {
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil nil];

    [alert show];
    }
    上面就是九宮格的代理方法(沒有列全,只是簡單實現了UICollectionView),上面的方法 看注釋。
    自定義UICollectionViewCell

重點是設置Cell的方法,我是使用了自定義Cell,這里就會顯示出UICollectionView 與 UITableview 的不同.
首先,UICollectionView 與UITableView 都有類似的
[objc] view plain copy
[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
這個是 Cell 的重用機制。UITableView 需要判斷Cell是否 為空
[objc] view plain copy
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
如果cell =nil 里面就可以使用 自定義 UITableViewCell 這里不再說了,但是UICollectionView 不需要判斷Cell 是否為nil,可以使用系統
的UICollectionViewCell 也可以使用自定義的UICollectionViewCell,我們一般用的就是自定義的Cell .
[objc] view plain copy

  • (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
    CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
    cell.imageName = self.dataSourceArray[indexPath.row];
    cell.backgroundColor = [UIColor whiteColor];

    return cell;
    }
    CollectionViewCell 就是我自定義的Cell ,imageName 是自定義Cell 里面添加的圖片的名字。
    我們先來看一下自定義UICollectionViewCell 的文件,我實現的Cell 很簡單就是添加了一個圖片(這個自定義Cell 可以根據需要
    自行設置),
    [objc] view plain copy
    .h 文件

import <UIKit/UIKit.h>

@interface CollectionViewCell : UICollectionViewCell

@property (nonatomic, copy) NSString *imageName;

@end

.m 文件

import "CollectionViewCell.h"

@interface CollectionViewCell ()
@property (nonatomic, strong) UIImageView *imageView;

@end

@implementation CollectionViewCell

  • (instancetype)initWithFrame:(CGRect)frame
    {
    self = [super initWithFrame:frame];
    if (self) {
    }
    return self;
    }

  • (void)setImageName:(NSString *)imageName
    {
    //注意cell里面的控件 使用的位置 是相對于cell 的位置的 所以使用bounds
    _imageName = imageName;
    _imageView = [[UIImageView alloc]initWithFrame:self.bounds];
    _imageView.image = [UIImage imageNamed:imageName];
    [self addSubview:_imageView];
    }

@end

這里返回cell 的方法好像只能寫
[objc] view plain copy

  • (instancetype)initWithFrame:(CGRect)frame
    我使用
    [objc] view plain copy

  • (instancetype)init
    {
    self = [super init];
    if (self) {

    }
    return self;
    }
    但是沒有執行,好了。我們知道使用
    [objc] view plain copy

  • (instancetype)initWithFrame:(CGRect)frame
    去初始化一個自定義的Cell 。
    自定義UICollectionViewCell 注意

這里我又連續碰到了2個問題,當然我上面粘貼出來出來的都是正確的。先說說第一個問題,我是在
[objc] view plain copy

  • (instancetype)initWithFrame:(CGRect)frame
    {
    self = [super initWithFrame:frame];
    if (self) {
    self.imageView = [[UIImageView alloc]initWithFrame:self.bounds];
    self.imageView.image = [UIImage imageNamed:self.imageName];
    [self addSubview:_imageView];
    }
    return self;
    }
    這里面根據我傳遞過來的圖片名字設置圖片的,但是圖片并沒有顯示出來。不知道你注意到了這個沒有
    [objc] view plain copy

  • (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
    CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
    cell.imageName = self.dataSourceArray[indexPath.row];
    cell.backgroundColor = [UIColor whiteColor];

    return cell;
    }
    這個自定義UICollectionViewCell 是直接使用重用機制,調用系統的Cell 實例方法,但是我們設置自定義Cell 的圖片信息,是在調用
    過系統的重用的實例方法 ,之后設置的。因為我們沒有辦法向自定義UITableViewCell 方法一樣,實現我們自定義的實例方法。這就
    導致了系統在調用我們 自定義UICollectionViewCell 的時候里面的imageName 字符串還是nil ,所以圖片顯示不出來。這里我使用了
    重寫setter方法,當然重寫setter的時候可以傳遞過來一個模型的數據,來設置Cell 里面的顯示的數據。
    [objc] view plain copy

  • (void)setImageName:(NSString *)imageName
    {
    //注意cell里面的控件 使用的位置 是相對于cell 的位置的 所以使用bounds
    _imageName = imageName;
    _imageView = [[UIImageView alloc]initWithFrame:self.bounds];
    _imageView.image = [UIImage imageNamed:imageName];
    [self addSubview:_imageView];
    }
    當我去設置 自定義Cell 里面的屬性 iamgeName 的時候再去 添加圖片。這樣圖片就能顯示出來了。
    最后一個問題,我在重寫setter方法的時候,設置cell的UIImageView frame的時候 ,出現的。顯示為UIImageView 的圖片位置
    不正確,能顯示出來的只有2列,當我點擊cell 提示的彈窗,提示信息跟我點擊的cell圖片不對應,最開始我以為是cell 的間距問題,
    調了兩次,發現還是調整不大。當我設置Cell 的背景顏色 為一個明顯的突出顏色的時候,就看出來問題的原因了。cell 的位置是正確
    的,錯誤的是cell的UIImageView 的位置。
    問題出現前:
    [objc] view plain copy
    _imageView = [[UIImageView alloc]initWithFrame:self.frame];
    問題解決:
    [objc] view plain copy
    _imageView = [[UIImageView alloc]initWithFrame:self.bounds];

問題的原因是,我設置UIImageView 的位置是 self.frame 這個位置是相對于整個UICollectionView 的,再添加自定義Cell 上面的時候,就不對了,那個位置是cell相對于父視圖 UICollectionView的,添加到Cell 上面的,UIImageView 的父視圖是Cell 而不是UICollectionView,所以設置圖片視圖UIImageView 的位置的時候應該用相對于Cell 位置的self.bounds .

以上,就是我在實現UICollectionView 的時候碰到的小問題,以及自定義UICollectionViewCell 。啦啦啦啦得意

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內容