iOS之表視圖UITableView運用技巧

主要提綱:

一、表視圖
二、UITableViewCell的重用機制
三、UITableview的相關配置(代理方法)
四、UITableView自適應高速
五、UITableView的編輯(增、刪、移動)
六、成品展示

一、表視圖(UItableView)

1、什么是表視圖?

表視圖 UITableView,iOS中最重要的視圖,隨處可 。
表視圖通常 來管理 組具有相同數據結構的數據。
例圖:


UITableView的使用圖片.png

二、UITableViewCell的重用機制

1、為什么要使用UITableViewCell的重用機制?
表視圖的重用機制:當表視圖的單元格超過一屏幕時,這時就會啟動cell重用機制。當滑動時單元格出屏幕時,就會把相同格式的單元格放在同一個集合中,為這個集合添加標識符,當我們需要使用某種樣式的單元格時,根據不同的標示符,從集合中尋找單元格,出屏幕的cell會被添加到mutableSet中,進入屏幕的cell,先從set中獲取,如果獲取不到,才創建一個cell。在cell顯示之前,給cell賦上相應的內容。
// 定義單元格    indexPath:單元格當前所在的位置
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    // 相當于從集合中找尋完全出屏幕的單元格
    // identifier: 因為一個表視圖中可能存在多種樣式的單元格,咋們把相同格式的單元格放在同一個集合里,為這個集合加標識符,當我們需要用到某種樣式的單元格時,根據不同的標識符,從集合中找尋單元格
    static NSString *identifier = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    // 如果從集合中未找到單元格,也就是集合中還沒有單元格,也就是還沒有單元格完全出屏幕,那么我們就需要創建單元格
    if (!cell) {
        // 創建cell的時候需要標示符,是因為當該cell觸屏幕的時候需要根據標示符放到對應的集合中
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
    }

三、UITableview的相關配置(代理方法)

1 、UITableView的創建與配置
#import "RootViewController.h"
@interface RootViewController ()<UITableViewDataSource,UITableViewDelegate>
@property (nonatomic,retain)NSArray *dataArray; // 數據源,用來給cell賦值的
@property (nonatomic,retain)NSArray *dataArray1;
@property (nonatomic,retain)NSDictionary *datadic;
@property (nonatomic,retain)NSMutableArray *titleArray;  // 用來盛放頭標題

@end

@implementation RootViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //  初始化數據源并且添加數據
    self.dataArray = [NSArray arrayWithObjects:@"小心如",@"林心如",@"趙薇",@"林志穎",
                                               @"LOL",@"劉毅",@"仝文哲",@"成龍",
                                               @"丁大",@"武松", nil];
    self.dataArray1 = [NSArray arrayWithObjects:@"大喬恩",@"陳喬恩",@"趙薇",@"林志穎",
                       @"LOL",@"劉毅",@"仝文哲",@"成龍",
                       @"丁大",@"武松", nil];

    self.datadic = [NSDictionary dictionaryWithObjectsAndKeys:self.dataArray,@"one",self.dataArray1,@"two", nil];
    

    // 添加頭標題
    for (NSArray *arrayIten in self.datadic.allValues) {
        // 從數組中取出第一個元素
        // 判斷字典中的元素釋放存在,如果存在它的類型是否是數組
        if (arrayIten && [arrayIten isKindOfClass:[NSArray class]] && arrayIten.count) {
            NSString *nameStr = [arrayIten objectAtIndex:0];
            // 判斷數組中的元素是否存在,如果存在類型是否為字符串,如果為字符串,判斷字符串長短是否為0
            if (nameStr && [nameStr isKindOfClass:[NSString  class]]  && nameStr.length) {
                // 截取字符串的首個字符
                NSString *resultStr = [nameStr substringToIndex:1];
                [self.titleArray addObject:resultStr];
                NSLog(@"%@",resultStr);
            }
            
        }
    }
    
   self.navigationItem.title = @"今日頭條";
    // 初始化一個UItableView
    //  style:設置單元格的樣式  有兩種樣式:plain(平鋪) group(分組)   默認是平鋪
    UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)) style:UITableViewStyleGrouped];
    // 設置分割線樣式
    tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    tableView.separatorColor = [UIColor greenColor];
    /**
     UITableViewCellSeparatorStyleNone,
     UITableViewCellSeparatorStyleSingleLine,
     UITableViewCellSeparatorStyleSingleLineEtched
     */
    // 如果我們每個cell的高度是統一的,可以直接使用屬性設置
    tableView.rowHeight = 200;
    tableView.backgroundColor = [UIColor orangeColor];
    //UItableView 的代理
    tableView.dataSource = self;
    tableView.delegate = self;
    [self.view addSubview:tableView];
}
2、相關代理
#pragma mark -- 共有多少個分區
// 共有多少個分區 (此方法是可選的,如果不實現該代理方法,默認整個表視圖只有一個分區)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    
    // 返回字典在中元素的個數,作為分區的個數
    return self.datadic.count;
}

#pragma mark -- 每個分區下返回的行數
// 每個分區下返回的行數
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    // 返回所有數據的個數 這里單元格的返回個數一般不寫死,將數據源的個數作為返回值,根據數據的數量來創建單元格的數量
//  return [self.dataArray count];
    
//    // 根據當前所在的分區,取得字典中對應的鍵
//    NSString *keyString = self.datadic.allKeys[section];
//    NSLog(@"%@",keyString);
//    // 根據鍵取出對應的值,由于字典的值為數組,所以可以有count屬性
//    return [self.datadic[keyString] count];
    
    // 根據所在分區取出字典中的(值)
    NSArray *array = [self.datadic.allValues objectAtIndex:section];
    return array.count;
}
#pragma mark -- 定義單元格
// 定義單元格    indexPath:單元格當前所在的位置
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    // 表視圖的重用機制:當表視圖的單元格超過一屏幕時,這時就會啟動cell重用機制。當滑動時單元格出屏幕時,就會把相同格式的單元格放在同一個集合中,為這個集合添加標識符,當我們需要使用某種樣式的單元格時,根據不同的標示符,從集合中尋找單元格
    
  //出屏幕的cell會被添加到mutableSet中,進入屏幕的cell,先從set中獲取,如果獲取不到,才創建一個cell。在cell顯示之前,給cell賦上相應的內容。
    
    static NSString *identifier = @"cell";
    // 相當于從集合中找尋完全出屏幕的單元格
    // identifier: 因為一個表視圖中可能存在多種樣式的單元格,咋們把相同格式的單元格放在同一個集合里,為這個集合加標識符,當我們需要用到某種樣式的單元格時,根據不同的標識符,從集合中找尋單元格
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    // 如果從集合中未找到單元格,也就是集合中還沒有單元格,也就是還沒有單元格完全出屏幕,那么我們就需要創建單元格
    if (!cell) {
        // 創建cell的時候需要標示符,是因為當該cell觸屏幕的時候需要根據標示符放到對應的集合中
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
        
        /*
         UITableViewCellStyleDefault,   // Simple cell with text label and optional image view (behavior of UITableViewCell in iPhoneOS 2.x)
         UITableViewCellStyleValue1,        // Left aligned label on left and right aligned label on right with blue text (Used in Settings)
         UITableViewCellStyleValue2,        // Right aligned label on left with blue text and left aligned label on right (Used in Phone/Contacts)
         UITableViewCellStyleSubtitle   // Left aligned label on top and left aligned label on bottom with gray text (Used in iPod).
         
        */
        
        // 設置cell的style,不涉及到數據的重新賦值,咋們可以在初始化cell的時候給他設定好
        // 設置輔助視圖的樣式 (枚舉值,有多種樣式)
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        /**
         UITableViewCellAccessoryNone,                                                      // don't show any accessory view
         UITableViewCellAccessoryDisclosureIndicator, //灰色小箭頭                                       // regular chevron. doesn't track
         UITableViewCellAccessoryDetailDisclosureButton // 藍圈號                // info button w/ chevron. tracks
         UITableViewCellAccessoryCheckmark,    // 對號                                              // checkmark. doesn't track
         UITableViewCellAccessoryDetailButton NS_ENUM_AVAILABLE_IOS(7_0)  __TVOS_PROHIBITED // info button.
         */
        
        
        // 設置選中后的效果
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        /**
         UITableViewCellSelectionStyleNone,
         UITableViewCellSelectionStyleBlue,
         UITableViewCellSelectionStyleGray,
         UITableViewCellSelectionStyleDefault
         */

    }
四、UITableView自適應高速
#pragma mark -- 自適應高速
// 返回cell高度的代理方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    // NSString有一個方法,可以根據內容返回一個矩形大小
    // 代理方法的執行是有順序的,這里視線執行返回高度的代理方法,在執行創建單元格的代理方法
    // 取得內容
    NSDictionary *dic = [self.dataArray objectAtIndex:indexPath.row ];
    NSString *contentStr = [dic objectForKey:@"content"];
    // 內容自適應高度的方法
    /**
     *  參數解釋:
     *  size:是規定文本顯示的最大范圍
     *  options:按照和中設置來計算范圍
     *  taaributes:文本內容的一些屬性,例如;字體大小。字體的類型
     *   context:上下文,可以規定一些其他設置,但是一般都是nil
     */
    
    // 枚舉值中的單或(|),意思是要滿足所有的枚舉值設置
    CGRect rect = [contentStr boundingRectWithSize:CGSizeMake(tableView.bounds.size.width, MAXFLOAT) options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15]} context:nil];
    
    return rect.size.height+60;
}
五、UITableView的編輯(增、刪、改)
1、 打開編輯狀態
  // 設置導航條右側編輯按鈕,如果設置表視圖為可編輯狀態,點擊此處按鈕就會有相應的操作
    self.navigationItem.rightBarButtonItem = self.editButtonItem;
// 設置表視圖的編輯狀態 (重寫系統的方法 ,而不是代理方法)
- (void)setEditing:(BOOL)editing animated:(BOOL)animated{
    [super setEditing:editing animated:animated];
    // 設置tableView為可編輯狀態
    [self.tableView setEditing:editing animated:animated];
}
2、 設置課編輯狀態下的表視圖哪個單元格可編輯,
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
    // 不想首個單元格可編輯
    if (indexPath.row == 0) {
        return NO;
    }
    // 直接返回YES,默認所有單元格都是可以編輯的
    return YES;
}
3. 設置編輯樣式
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
    // 讓最后一行為插入數據樣式
    if (indexPath.row == (self.dataMutableArray.count - 1)) {
        return UITableViewCellEditingStyleInsert;
    }
    // 默認所有的單元格都是刪除樣式
    return  UITableViewCellEditingStyleDelete;
}
4、編輯(刪除,增加)
// 編輯完成之后執行的代理方法
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    // 此方法根據編輯樣式的不同,來做出不同的邏輯操作
    // 如果編輯樣式為刪除是執行的操作
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // 先刪除當前單元格上現實的數據
        [self.dataMutableArray removeObjectAtIndex:indexPath.row];
        // 刪除單元格
        
        /**
          indexPaths:此參數為數組,數組中的元素類型是NSIndexPath類型,說明此方法可以刪除多個單元格
         Animation:刪除動作的動畫
         */
    
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:  UITableViewRowAnimationBottom];
        
    }else if (editingStyle == UITableViewCellEditingStyleInsert){
        // 先增加一條數據
//        [self.dataMutableArray insertObject:@"叼毛獸" atIndex:indexPath.row];
       [self.dataMutableArray insertObject:@"叼毛獸" atIndex:self.dataMutableArray.count - 1];

        // 在增加單元格
        [tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
    }
}
4、編輯(移動單元格)

// 移動單元格

- (BOOL) tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath{
    // 默認YES,所有的單元格都可以移動
    return YES;
}
//
/** 移動完成會執行的代理方法
 *  @param sourceIndexPath  當前移動單元格原來所在的位置
 *  @param destinationIndexPath 移動完成后所在的新位置
 */
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
    // 把要移動位置的數據先保存起來
    NSString *string = [NSString stringWithString:[self.dataMutableArray objectAtIndex:sourceIndexPath.row]];
    // 刪除原來位置的數據
    [self.dataMutableArray removeObjectAtIndex:sourceIndexPath.row];
    
    // 把此數據插入到數組中新位置
    [self.dataMutableArray insertObject:string atIndex:destinationIndexPath.row];
  
}

六、成品展示

1、成品


5F11AA6F-8C6A-4990-A753-3C1F72D10F3F.png

2、移動

097AA0D8-BBE6-4E8C-A9C1-6EE2235A5DCD.png

3、刪除

370316CA-B9C5-4844-BC4D-C921B71A0967.png

4、增加

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

推薦閱讀更多精彩內容