iOS學(xué)習(xí)筆記之UITableView(1)

序引

本系列文章將介紹iOS開發(fā)中的UITableView控件,將會分成四篇文章完整的講述UITableView的具體使用方法和注意點,文章編寫周期會長一些,由于本人還在學(xué)習(xí)iOS開發(fā)階段,有些東西可能會描述不對或錯誤,Markdown排版也不是特別好,歡迎各位讀者指點其中不對的地方。


本文主要涉及的知識點:

  1. UITableView的概念
  2. UITableView顯示數(shù)據(jù)的兩種樣式
  3. UITableView的使用步驟
  4. UITableView的常見屬性
  5. UITableViewCell的基本概念
  6. UITableViewCell的常見屬性
  7. UITableView的代理方法
  8. UITableViewController的講解
  9. UITableViewCell的重用

1. UITableView的概念

  • 在iOS開發(fā)中,要實現(xiàn)展示列表數(shù)據(jù),就常用的做法就是使用UITableView
  • UITbaleView繼承自UIScrollView,因此支持垂直滾動,而且性能極佳


2. UITableView顯示數(shù)據(jù)的兩種樣式

  • 單組樣式
    • UITableViewStylePlain
    • 展示單組數(shù)據(jù),沒有分組
    • 例如:


      01.png
  • 分組樣式
    • UITableViewStyleGrouped
    • 展示多組數(shù)據(jù),有分組,每一組可以有不同的行數(shù)
    • 例如:


      02.png


3. UITableView的使用步驟

  • 第一步:設(shè)置數(shù)據(jù)源對象

    • self.tableView.dataSource = self;
    • 數(shù)據(jù)源對象一般設(shè)置為當(dāng)前控制器
    • 設(shè)置的語句寫在控制器的- (void)viewDidLoad方法中
      - (void)viewDidLoad {
          [super viewDidLoad];
      
          // 設(shè)置數(shù)據(jù)源對象為當(dāng)前控制器
          self.tableView.dataSource = self;
      }
      
  • 第二步:設(shè)置的數(shù)據(jù)源對象要遵守協(xié)議

    • 設(shè)置為數(shù)據(jù)源對象的類一定要遵守UITableViewDataSource協(xié)議
      @interface ViewController () <UITableViewDataSource>
      
      @end
      
  • 第三步:實現(xiàn)數(shù)據(jù)源協(xié)議中的方法

    • 單組數(shù)據(jù)必須實現(xiàn)數(shù)據(jù)源中的兩個方法

    • 多行數(shù)據(jù)必須實現(xiàn)數(shù)據(jù)源中的三個方法

    • - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

      • 告訴tableView一共有多少組數(shù)據(jù)
      • 單組數(shù)據(jù)可以不用實現(xiàn)(因為只有一組數(shù)據(jù),系統(tǒng)默認(rèn)為1),多組數(shù)據(jù)必須實現(xiàn)
      • 參數(shù)section:傳入當(dāng)前是第幾組,當(dāng)樣式為單組數(shù)據(jù)的時候,section永遠(yuǎn)為0
        - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
        {
            return 4;
        }
        
    • - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

      • 告訴tableView每一組有多少行數(shù)據(jù)
      • 單組數(shù)據(jù)和多組數(shù)據(jù)都必須實現(xiàn)
      • 參數(shù)section:傳入當(dāng)前是第幾組
      • 參數(shù)
        - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
        {
            if (section == 0) {
                return 2; // 第0組有兩行數(shù)據(jù)
            } else if (section == 1) {
                return 6; // 第1組有六行數(shù)據(jù)
            } else if (section == 2) {
                return 6; // 第2組有六行數(shù)據(jù)
            } else {
                return 1; // 第3組有一行數(shù)據(jù)
            }
        }
        
    • - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

      • 告訴tableView每一行顯示的內(nèi)容
      • tableView每一行的內(nèi)容一定是UITableViewCell
      • 單組數(shù)據(jù)和多組數(shù)據(jù)都必須實現(xiàn)
      • 參數(shù)indexPath:indexPath有兩個屬性,indexPath.section傳入當(dāng)前是第幾組,indexPath.row傳入當(dāng)前是第幾行
        - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
        {
            UITableViewCell *cell = [[UITableViewCell alloc] init];
        
            if (indexPath.section == 0) {
                if (indexPath.row == 0) {
                    // 第0組第0行顯示的數(shù)據(jù)為“通用”
                    cell.textLabel.text = @"通用";
                } else if (indexPath.row == 1) {
                    // 第0組第1行顯示的數(shù)據(jù)為“隱私”
                    cell.textLabel.text = @"隱私";
                }
            } else {
                // 其他組顯示的數(shù)據(jù)為自己的組號和行號
                cell.textLabel.text = [NSString stringWithFormat:@"%zd組%zd行-其他數(shù)據(jù)", indexPath.section,indexPath.row];
            }
            return cell;
          }
        
    • - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

      • 告訴tableView每一組的頭部標(biāo)題
      • 參數(shù)section:傳入當(dāng)前是第幾組
        - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
        {
            if (section == 0) {
                return @"頭部標(biāo)題";
            } else {
                return @"頭部標(biāo)題";
            }
        }
        
    • - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section

      • 告訴tableView每一組的尾部標(biāo)題
      • 參數(shù)section:傳入當(dāng)前是第幾組
        - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
        {
            if (section == 0) {
                return @"尾部標(biāo)題";
            } else {
                return @"尾部標(biāo)題";
            }
        }
        


4. UITableView的常見屬性

  • 設(shè)置行高的高度:

    屬性:
    @property (nonatomic) CGFloat rowHeight;
    
    使用格式:
    self.tableView.rowHeight = 70;
    
    說明:
    默認(rèn)是44
    
  • 設(shè)置每一組的頭部高度:

    屬性:
    @property (nonatomic) CGFloat sectionHeaderHeight;
    
    使用格式:
    self.tableView.sectionHeaderHeight = 50;
    
  • 設(shè)置分割線的顏色:

    屬性:
    @property (nonatomic, strong) UIColor *separatorColor
    
    使用格式:
    self.tableView.separatorColor = [UIColor redColor];
    
    說明:
    設(shè)置[UIColor clearColor]代表隱藏分割線,[UIColor clearColor]為透明色對象
    
  • 設(shè)置分割線的樣式:

    屬性:
    @property (nonatomic) UITableViewCellSeparatorStyle separatorStyle
    
    使用格式:
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    
    枚舉UITableViewCellSeparatorStyle常用的枚舉元素:
    UITableViewCellSeparatorStyleNone // 隱藏分割線
    UITableViewCellSeparatorStyleSingleLine // 默認(rèn)樣式
    UITableViewCellSeparatorStyleSingleLineEtched // 僅支持在grouped樣式,但是和默認(rèn)樣式?jīng)]什么區(qū)別
    
  • 設(shè)置表頭控件:

    屬性:
    @property (nonatomic, strong) UIView *tableHeaderView;
    
    使用格式:
    self.tableView.tableHeaderView = [[UISwitch alloc] init];
    
  • 設(shè)置表尾控件:

    屬性:
    @property (nonatomic, strong) UIView *tableFooterView;
    
    使用格式:
    self.tableView.tableFooterView = [[UISwitch alloc] init];
    


5. UITableViewCell的基本概念

  • UITableView的每一行都是一個UITableViewCell
  • UITableView內(nèi)部有個默認(rèn)的子控件:contentView,填充整個UITableViewCell的父控件
  • UITableView的子控件實質(zhì)都在contentView


6. UITableViewCell的常見屬性

  • 設(shè)置cell右邊的指示控件:

    屬性:
    @property (nonatomic, strong) UIView *accessoryView;
    
    使用格式:
    cell.accessoryView = [[UISwitch alloc] init];
    
  • 設(shè)置cell右邊的指示樣式:

    屬性:
    @property (nonatomic) UITableViewCellAccessoryType accessoryType;
    
    使用格式:
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    
    枚舉UITableViewCellSeparatorStyle常用的枚舉元素:
    UITableViewCellSeparatorStyleNone // 隱藏分割線
    UITableViewCellSeparatorStyleSingleLine // 默認(rèn)樣式
    UITableViewCellSeparatorStyleSingleLineEtched //
    
  • 設(shè)置cell的選中樣式:

    屬性:
    @property (nonatomic) UITableViewCellSelectionStyle selectionStyle;
    
    使用格式:
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    
    枚舉UITableViewCellSelectionStyle常用的枚舉元素:
    UITableViewCellSelectionStyleNone // 不能選中
    UITableViewCellSelectionStyleBlue
    UITableViewCellSelectionStyleGray
    UITableViewCellSelectionStyleDefault
    
  • 設(shè)置cell的背景控件:

    屬性:
    @property (nonatomic, strong) UIView *backgroundView;
    
    使用格式:
    UIView *bg = [[UIView alloc] init];
    bg.backgroundColor = [UIColor redColor];
    cell.backgroundView = bg;
    
  • 設(shè)置cell的背景顏色:

    屬性:
    @property(nullable, nonatomic,copy) UIColor *backgroundColor
    
    使用格式:
    cell.backgroundColor = [UIColor blueColor];
    
    說明:
    還可以設(shè)置cell的子控件背景圖片
    cell.textLabel.backgroundColor = [UIColor greenColor];
    
  • 設(shè)置cell選中的背景view:

    屬性:
    @property (nonatomic, strong) UIView *selectedBackgroundView;
    
    使用格式:
    UIView *seletedBg = [[UIView alloc] init];
    seletedBg.backgroundColor = [UIColor purpleColor];
    cell.selectedBackgroundView = seletedBg;
    


7. UITableView的代理方法

  • 當(dāng)選中某一行cell的時候就會調(diào)用這個方法:

    方法聲明:
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
    
    使用格式:
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSLog(@"選中第%zd行", indexPath.row);
    }
    
  • 當(dāng)取消選中某一行cell的時候就會調(diào)用這個方法:

    方法聲明:
    - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath;
    
    使用格式:
    - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSLog(@"取消選中第%zd行", indexPath.row);
    }
    
  • 返回每一組的頭部控件:

    方法聲明:
    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
    
    使用格式:
    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
        return [UIButton buttonWithType:UIButtonTypeContactAdd];
    }
    
  • 返回每一組的尾部控件:

    方法聲明:
    - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
    
    使用格式:
    - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
    {
        return [[UISwitch alloc] init];
    }
    
  • 返回每一組的頭部高度:

    方法聲明:
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
    
    使用格式:
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
    {
        return 100;
    }
    
  • 返回每一組的尾部高度:

    方法聲明:
    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
    
    使用格式:
    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
    

{
return 100;
}


- 返回每一行cell的高度:
```objc
方法聲明:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

使用格式:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 0) {
        return 100;
    } else {
        return 50;
    }
}


8. UITableViewController的講解

  • 將控制器設(shè)置為UITableView的方法和步驟

    • 第一步:創(chuàng)建新的類或修改原有的ViewController類,繼承自UITableViewController
    • 第二步:在Main.storyboard中刪除自帶的UIViewController控制器,然后往里面拖一個UITableViewController控制器
      03.png
    • 第三步:修改新拖進(jìn)來的TableViewController控制器的自定義類名為第一步中繼承自UITableViewController類的類名
      04.png
    • 第四步:勾選TableViewController控制器為程序啟動第一個加載的控制器
      05.png
  • 注意點:

  • tableVieController有個tableView屬性,指向一個tableView

  • tableViewdataSourcedelegate屬性指向的就是這個控制器,并且這個控制器已經(jīng)遵守了UITableViewDataSourceUITableViewDelegate

  • 每個控制器的內(nèi)部都有一個view屬性,在tableVieController中,viewtableView屬性指向的是同一個對象(控制器的view就是tableView



9. UITableViewCell的重用

  • 原因
    • iOS設(shè)備的內(nèi)存有限,如果用UITableView顯示成千上萬條數(shù)據(jù),就需要成千上萬個UITableViewCell對象的話,那將會耗盡iOS設(shè)備的內(nèi)存
    • 要解決該問題,需要重用UITableViewCell對象
  • 原理:
    • 當(dāng)滾動列表時,部分UITableViewCell會移出窗口,UITableView會將窗口外的UITableViewCell放入一個緩存池中,等待重用
    • 當(dāng)UITableView要求dataSource返回UITableViewCell時,dataSource會先查看這個對象池,如果池中有未使用的UITableViewCelldataSource會用新的數(shù)據(jù)配置這個UITableViewCell,然后返回給UITableView,重新顯示到窗口中,從而避免創(chuàng)建新的UITableViewCell對象
  • Cell重用的實現(xiàn)代碼
    • 方法一:

      1. 定義一個cell的重用標(biāo)識
      2. 根據(jù)這個ID去緩存池中看有沒有可循環(huán)利用的cell
      3. 如果緩存池中沒有可循環(huán)利用的cell,自己創(chuàng)建
      - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
      {
              // 1. 定義一個重用標(biāo)識
              static NSString *ID = @"A";
      
              // 2. 根據(jù)這個ID去緩存池中看有沒有可循環(huán)利用的cell
              UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"A"];
      
              // 3. 如果緩存池中沒有可循環(huán)利用的cell, 自己創(chuàng)建
              if (cell == nil) {
                  cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"A"];
              }
              return cell;
      }
      
    • 方法二:

      1. 定義一個cell的重用標(biāo)識
      2. 根據(jù)這個ID去緩存池中看有沒有可循環(huán)利用的cell
      3. 如果緩存池中沒有會看有沒有根據(jù)ID這個標(biāo)識注冊對應(yīng)的cell類型
      4. 如果有注冊,會根據(jù)這個ID創(chuàng)建對應(yīng)的類型的cell,并且會綁定這個ID標(biāo)識,返回這個cell
      // 1. 定義一個重用標(biāo)識
      static NSString *ID = @"A";
      
      - (void)viewDidLoad
      {
             [super viewDidLoad];
      
             // 3. 根據(jù)ID 這個標(biāo)識 注冊 對應(yīng)的cell類型是UITableViewCell
             [self.tableView registerClass:[YTTableViewCell class] forCellReuseIdentifier:ID];
      }
      
      - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
      {
               // 2. 根據(jù)這個ID去緩存池中看有沒有可循環(huán)利用的cell
               YTTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
      
               return cell;
      }
      
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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