D13:自定義UITableViewCell

自定義Cell時Cell的控件都是添加到Cell的contentView上
KVC方法設置屬性值, 快速創建數據源

- (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues
[model setValuesForKeysWithDictionary:dict];

使用XIB方式時新建Cell對象時使用

- (NSArray *)loadNibNamed:(NSString *)name owner:(id)owner options:(NSDictionary *)options
cell = [[[NSBundle mainBundle] loadNibNamed:@"BookCell" owner:self options:nil] lastObject];


一.代碼自定義 "UITableViewCell"

題目要求:根據plist文件準備數據源, 并創建模型
  1. 根據需求和plist文件創建模型類

  • 創建數據源(數據源數組中的數據是模型對象): 從plist文件中獲取數據

  • 新建tableView

  • 核心:自定義Cell

    // 自定義cell
    // 繼承于UITableViewCell創建一個類型
    // 然后添加需要的視圖, 用來顯示數據
    @interface BookCell : UITableViewCell
    
    // 左邊的圖片, 需要注意: 不要和父類的imageView屬性沖突
    @property (nonatomic, strong) UIImageView *bookImageView;
    // 書名,      需要注意: 不要和父類的textLabel和DetailTextLable屬性沖突
    @property (nonatomic, strong) UILabel *nameLabel;
    // 價格
    @property (nonatomic, strong) UILabel *prcieLabel;
    // 描述
    @property (nonatomic, strong) UILabel *descLabel;
    
    // 顯示數據
    - (void)config:(BookModel *)model;
    
    @end
    
    
    • 重寫- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
      - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {
            // 初始化視圖對象
            // 圖片
            _bookImageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 10, 60, 60)];
            // 添加到父視圖
            // 自定義cell的時候, 所有視圖都添加到cell的contentView中
            [self.contentView addSubview:_bookImageView];
            
            // 書名
            _nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 5, 200, 20)];
            [self.contentView addSubview:_nameLabel];
            
            // 價格
            _prcieLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 30, 200, 20)];
            [self.contentView addSubview:_prcieLabel];
            
            // 描述
            _descLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 55, 200, 20)];
            [self.contentView addSubview:_descLabel];
        }
        return self;
    }
    
    
    • 自定義Cell中顯示數據的方法
      - (void)config:(BookModel *)model
      {
          self.bookImageView.image = [UIImage imageNamed:model.icon];
          self.nameLabel.text = model.name;
          self.prcieLabel.text = model.price;
          self.descLabel.text = model.detail;
      }
    
  • DataSource方法

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *cellID = @"cellID";
        BookCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
        if (nil == cell) {
            cell = [[BookCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
        }
        [cell config:self.dataArray[indexPath.row]];
        
        return cell;
    }
    

二. 代碼自定義Cell為一個ScrollView加上其他控件的效果

  1. 初步創建廣告數據的模型類
    #import <Foundation/Foundation.h>
    
    @interface AdModel : NSObject
    
    // 圖片
    @property (nonatomic, strong) NSString *imageName;
    // 標題文字
    @property (nonatomic, strong) NSString *title;
    
    @end  
    
  2. 準備廣告cell的數據源

    @property (nonatomic, strong) NSMutableArray *adArray;

    // 創建廣告cell對應的數據
    - (void)createAdvertisementData
    {
        // 數據源數組
        _adArray = [NSMutableArray array];
        
        for (int i = 0; i < 4; i++) {
            AdModel *model = [[AdModel alloc] init];
            model.imageName = [NSString stringWithFormat:@"image%d", i];
            model.title = [NSString stringWithFormat:@"第%d個標題", i+1];
            [_adArray addObject:model];
        }
    
    }
      
    
  3. 核心: 自定義Cell

    • AdCell.h
    @interface AdCell : UITableViewCell
        
    // 滾動視圖, 用來顯示圖片
    @property (nonatomic, strong) UIScrollView *scrollView;
    // 底部的背景視圖(只需顯示顏色)
    @property (nonatomic, strong) UIView *bgView;
    // 標題文字
    @property (nonatomic, strong) UILabel *titleLabel;  
    // UIPageControl
    @property (nonatomic, strong) UIPageControl *pageCtrl;
    
    // 顯示數據(如果是之前的config: 方法, 相當于只是setter方法)
    @property (nonatomic, strong) NSArray *adArray;
        
    @end
        
    
    • AdCell.m
   #import "AdCell.h"
   #import "AdModel.h"
   #define kHeightOfStatusBar 20
   #define kHeightOfAssemble 44
   #define kHeightOfNavigationAndStatusBar 64
   #define kBoundsOfScreen [[UIScreen mainScreen] bounds]
   #define kWidthOfScreen [[UIScreen mainScreen] bounds].size.width
   #define kHeightOfScreen [[UIScreen mainScreen] bounds].size.height
   
   @implementation AdCell
   
   // 重寫父類的方法
   - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
   {
       self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
       if (self) {
           // 初始化視圖
           // 1. 滾動視圖
           _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, kWidthOfScreen, 160)];
           [self.contentView addSubview:_scrollView];
           
           // 2. 背景視圖
           _bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 130, kWidthOfScreen, 30)];
           _bgView.backgroundColor = [UIColor grayColor];
           // 設置透明度
           _bgView.alpha = 0.5;
           [self.contentView addSubview:_bgView];
           
           // 3. 標題文字
           _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 130, 120, 30)];
           _titleLabel.textColor = [UIColor whiteColor];
           [self.contentView addSubview:_titleLabel];
           
           // 4. pageCtrl
           _pageCtrl = [[UIPageControl alloc] initWithFrame:CGRectMake(160, 130, kWidthOfScreen - 180, 30)];
           [self.contentView addSubview:_pageCtrl];
       }
       return self;
   }
   
   // 重新實現setter方法
   - (void)setAdArray:(NSArray *)adArray
   {
       _adArray = adArray;
       
       // 添加額外的功能
       // 1.滾動視圖: 顯示4張圖片
       for (int i = 0; i < adArray.count; i++) {
           // 創建圖片視圖對象
           AdModel *model = adArray[i];
           UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(i*kWidthOfScreen, 0, kWidthOfScreen, CGRectGetHeight(self.scrollView.frame))];
           imageView.image = [UIImage imageNamed:model.imageName];
           //UIViewContentModeScaleToFill:圖片被拉伸(比例可能不變)以充滿整個imageView
           //UIViewContentModeScaleAspectFit:圖片被拉伸,比例不變,圖片的長邊剛好與imageview一樣
           //UIViewContentModeScaleAspectFill:圖片被拉伸,比例不變,圖片的短邊與imageview一致,圖片有可能超出imageview
           imageView.contentMode = UIViewContentModeScaleAspectFit;
           [self.scrollView addSubview:imageView];
       }
       self.scrollView.contentSize = CGSizeMake(kWidthOfScreen*adArray.count, 160);
       
       // 2. 背景視圖無需改動
       
       // 3. 標題文字
       if (adArray.count > 0) {
           AdModel *model = adArray[0];
           // 顯示標題
           self.textLabel.text = model.title;
       }
   
       // 4. pageCtrl
       _pageCtrl.numberOfPages = adArray.count;
       _pageCtrl.currentPage = 0;
   }
  • 修改tableView相關協議方法的實現, 使其能夠顯示
    #pragma mark - DataSource
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
    //    return self.dataArray.count;
        // 廣告的顯示占一個Cell
        return self.dataArray.count + 1;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row == 0) {
            // 廣告cell
            static NSString *adCellID = @"adCell";
            AdCell *cell = [tableView dequeueReusableCellWithIdentifier:adCellID];
            if (nil == cell) {
                cell = [[AdCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:adCellID];
            }
            
            cell.adArray = self.adArray;
            
            return cell;
        }
        // 書籍cell
        static NSString *cellID = @"cellID";
        BookCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
        if (nil == cell) {
            cell = [[BookCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
        }
        [cell config:self.dataArray[indexPath.row - 1]];
        
        return cell;
    }
    
    #pragma mark - Delegate
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row == 0) {
            // 廣告cell
            return 160;
        }
        return 80;
    }
    

三. xib方式自定義Cell

  1. 創建模型, 創建導航欄, 普通方法創建數據源

  • kvc方法設置屬性值

    • 普通方法創建數據源

model.title = dict[@"title"];
model.icon = dict[@"icon"];
model.price = dict[@"price"];
model.detail = dict[@"detail"];
```

  • 用KVC方法設置屬性值, 快速創建數據源

// 用字點數據轉成對象時, 如果字典的key值和對象的屬性名稱一一對應, 可以用kvc來設置屬性值
[model setValuesForKeysWithDictionary:dict];
```

  • 創建tabview對象,遵守協議實現協議方法

  • 完成自定義cell前工作

  • 創建BookCell(切記設置Cell的重用標記)

XIB連線圖
  • 創建滾動視圖的模型和廣告cell的數據源

 /*
         第一個參數: xib文件的名字
         第二個參數: 對象的所有者(可以傳self, 也可以傳nil)
         第三個參數: 選項參數(傳nil)
         */
        cell = [[[NSBundle mainBundle] loadNibNamed:@"BookCell" owner:self options:nil] lastObject];
  • 創建并書寫完成AdCell(切記設置AdCell的重用標記)

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

推薦閱讀更多精彩內容