Xcode控件使用筆記四:UITableView

UITableView的兩種內置樣式:UITableViewStylePlain  和 UTTableViewStyleGrouped(分組)

1、分組例子 : storyboard選擇一個UITableView,style設置爲Grouped

//  ViewController.m
#pragma mark - 數據源方法
#pragma mark 一共有多少組數據
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 2;
}
#pragma mark 第section組有多少行數據
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
}
#pragma mark 返回每一行顯示的具體數據
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 組 indexPath.section
    // 行 indexPath.row
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
    // 設置cell上面顯示的文本數據
    cell.textLabel.text = city;
    
    return cell;
}
#pragma mark 第section組的標題 
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
}
#pragma mark
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
}
#pragma mark 右側快捷分組
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    return self.provinces;
    //return @[@"A", @"B", @"C"];
}

2、單組例子 

UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
    
    // 圖片的文件名
    NSString *name = [NSString stringWithFormat:@"00%d.png", indexPath.row + 1];
    
    // 設置左邊的圖標
    cell.imageView.image = [UIImage imageNamed:name];
    // 設置主標題
    cell.textLabel.text = @"123213213";
    // 設置副標題
    cell.detailTextLabel.text = @"詳細描述------";
    
    // 設置cell的右邊箭頭樣式 ->
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    
    return cell;

#pragma mark - 代理方法
#pragma mark 選中了某一行就會調用
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //NSLog(@"--------%d", indexPath.row);
    
    // 1.獲得被點擊這行對應的產品信息
    MJProduct *p = self.data[indexPath.row];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息" message:nil
                                                   delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil];
    
    // 保存點擊的行號
    alert.tag = indexPath.row;
    
    // 設置alertView的樣式
    alert.alertViewStyle = UIAlertViewStylePlainTextInput;
    
    // 取出文本輸入框
    [alert textFieldAtIndex:0].text = p.name;
    
    // 顯示對話框
    [alert show];
}

#pragma mark - ALertView代理方法
#pragma mark 點擊了AlertView的某個按鈕時調用
/*
 
 刷新數據:
 1> 更改模型屬性
 2> 刷新UI界面(reloadDat43a)
 */
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1)
    { // 點擊了確定按鈕
        // 1.取得文本框的文字
        NSString *name = [alertView textFieldAtIndex:0].text;
        //NSLog(@"%@", name);
        
        // 2.更新數據(alertView.tag 就是 行號)
        MJProduct *p = self.data[alertView.tag];
        //NSLog(@"%@", p.name);
        p.name = name;
        
        // 3.刷新界面
        /*
         重新加載數據:
         重新向數據源請求數據(重新調用數據源的相應方法)
         
         會刷新所有的數據
         *///[self.tableView reloadData];
        
        // 局部刷新
        NSIndexPath *path = [NSIndexPath indexPathForRow:alertView.tag inSection:0];
        [self.tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationLeft];
    }
}

3、性能優化

1)緩衝池--重用機制:

cellForRowAtIndexPath方法根據新增一定數量的cell對象( view的高度/cell的高度),不會一下子新增所有(關鍵點在"一個屏幕顯示的cell數量"是有限的

dequeueReusableCellWithIdentifier,從字面上理解是“出列的可重用的cell”

reuse機制就是這樣。當cell需要顯示的時候,從queue裏面找,找到了,設置一下內容,顯示出來
滾動界面當有cell被移出屏幕時,把這個cell丟到queue裏面
顯示新的cell時,如果有“相同類型”(identifier)的cell,就從隊列拿一個出來,設置數據,顯示出來
至於queue裏面會有多少cell,這個會自動控制

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    // 0.用static修飾的局部變量,只會初始化一次< # # >
    static NSString *ID = @"Cell";
    
    // 1.拿到一個標識先去緩存池中查找對應的Cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    // 2.如果緩存池中沒有,才需要傳入一個標識創建新的Cell
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }
    
    // 3.覆蓋數據
    cell.textLabel.text = [NSString stringWithFormat:@"fdsfdsf-%d", indexPath.row];
    NSLog(@"---cellForRowAtIndexPath--%p--%d",cell,indexPath.row);
    
    return cell;

}

4、編輯模式

#pragma mark 提交編輯操作(點擊了"刪除"或者"+"按鈕)時調用
// 實現了這個方法,就有左劃刪除功能
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle  forRowAtIndexPath:(NSIndexPath *)indexPath
{
    //NSLog(@"------commit---%d", indexPath.row);
    
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // 刪除
        // 1.更改數據(刪除本行的數據)
        [self.mydata removeObjectAtIndex:indexPath.row];
        
        // 2.刷新UI界面
        //[tableView reloadData];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
    } else {
        // 添加
        
        // 1.更改數據(添加數據)
        // [self.mydata addObject:@"hahahhahah"];添加到最後面去了
        // 插入數據到本行的後面
        [self.mydata insertObject:@"新添加的數據...." atIndex:indexPath.row + 1];
        
        // 2.刷新UI界面
        //[tableView reloadData];
        
        // 刷新指定行(個數不變)
        //[tableView reloadRowsAtIndexPaths:<#(NSArray *)#> withRowAnimation:<#(UITableViewRowAnimation)#>];
        // 刪除指定行
        //[tableView deleteRowsAtIndexPaths:<#(NSArray *)#> withRowAnimation:<#(UITableViewRowAnimation)#>];
        // 插入新的行
        
        NSIndexPath *newPath = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:0];
        [tableView insertRowsAtIndexPaths:@[newPath] withRowAnimation:UITableViewRowAnimationTop];
    }
    /*
     
     */
}

#pragma mark 開啓編輯模式時,用到的移動方法
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    // 取出即將要刪除的數據
    NSString *data = self.mydata[sourceIndexPath.row];
    
    // 刪除需要移動的那一行
    [self.mydata removeObject:data];
    
    // 插入之前刪除的數據
    [self.mydata insertObject:data atIndex:destinationIndexPath.row];
    
    //NSLog(@"%d --> %d", sourceIndexPath.row, destinationIndexPath.row);
}

#pragma mark - 代理方法
#pragma mark 當tableview開啓編輯模式就會調用
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //return indexPath.row%2 ? UITableViewCellEditingStyleDelete : UITableViewCellEditingStyleInsert;
    return tableView.tag;
}

//UITableViewCellEditingStyle _style;

#pragma mark - 監聽item的點擊
#pragma mark 刪除
- (IBAction)remove
{
    self.tableView.tag = UITableViewCellEditingStyleDelete;
    
    //_style = UITableViewCellEditingStyleDelete;
    
    // 0.取出當前的編輯狀態
    BOOL edt = self.tableView.editing;
    
    // 1.開啓編輯模式
    //self.tableView.editing = YES;
    //[self.tableView setEditing:YES];
    // 帶有動畫效果
    [self.tableView setEditing:!edt animated:YES];
}

- (IBAction)add
{
    self.tableView.tag = UITableViewCellEditingStyleInsert;
    //_style = UITableViewCellEditingStyleInsert;
    
    //NSLog(@"add------");
    // 0.取出當前的編輯狀態
    BOOL edt = self.tableView.editing;
    
    // 1.開啓編輯模式
    [self.tableView setEditing:!edt animated:YES];
}

 一、刪除\添加:

 1.開啓編輯模式

 [self.tableView setEditing:YES animated:YES];

 2.實現數據源的某個方法

 tableView:commitEditingStyle:forRowAtIndexPath:

 3.下面方法的返回值決定編輯模式是添加還是刪除

 - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath

 二、排序:

 實現下面的方法即可:

 tableView:moveRowAtIndexPath:toIndexPath:

 三、4個刷新UI界面的方法

 1.添加新的行

 [tableView insertRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationTop];

 2.刪除指定的行

 [tableView deleteRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationTop];

 3.局部刷新指定的行

 [tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationTop];

 4.整體刷新所有的行

 [tableView reloadData];



發佈了28 篇原創文章 · 獲贊 7 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章