天天看點

iOS個人整理19-UITableViewController和UITableView的編輯

一、UITableViewController

UITableViewController是繼承于UIViewController中的一個類,隻不過比UIViewController中多了一個屬性tableView。

也就是說UITableViewController是自帶table的視圖控制器。

它的self.view 是UITableView而不是UIView。

dataSource和delegate都預設是self。

總而言之,省了不少事情,相當于建立了一個UIViewController并在上面聲明了完整的UITableView。

二、UITableView的編輯

對于UITableView來說,經常需要删除或者添加一條資訊,比如,通訊錄中的滑動删除和添加資訊。

簡單來說就是對單元格進行删除,添加,插入,以及調換順序的操作。

這些操作主要通過各種代理方法來實作

1.讓tableView處于編輯狀态

//系統提供的方法按鈕會調用此方法,讓tableView處于編輯狀态
-(void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    //設定父類進入編輯狀态
    [super setEditing:editing animated:animated];
    
    //開啟表視圖的編輯狀态
    UITableView *tempTableView = [self.view viewWithTag:1000];
    [tempTableView setEditing:editing animated:animated];
    
}

//确定cell是否可以進入編輯狀态,為NO就不能進入編輯狀态
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
           

2.設定編輯狀态的style,決定插入或删除

//設定編輯的樣式
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //如果是最後一行,編輯模式為插入
    if (indexPath.row == _allDataMutableArray.count-1) {
        return UITableViewCellEditingStyleInsert;
    }
    else
        return UITableViewCellEditingStyleDelete;
}
           

3.編輯狀态的送出,對tableView進行改變

//編輯狀态的送出
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableView *tempTableView = [self.view viewWithTag:1000];
   //如果編輯模式為删除
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        //先删除資料源,也就是數組中的内容
        [_allDataMutableArray removeObjectAtIndex:indexPath.row];
        
        //再删除單元格
        //這裡要特别注意,必須先操作資料再操作單元格,不然崩的不要不要的
        [tempTableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
    }
    
    //如果編輯模式為插入
    if (editingStyle == UITableViewCellEditingStyleInsert) {
        //先插入到數組
        [_allDataMutableArray insertObject:@"新人" atIndex:indexPath.row];
        //再建立單元格
        [tempTableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
    }
}
           

下面是移動單元格的方法

1.首先還是要進入編輯狀态,與上面第一步相同

2.設定是否可以移動

//實作協定,告訴tableView是否能移動
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
           

3.檢測移動的過程,可以對移動的源位置和目的位置進行限制

//監測移動過程,限制最後一行不能移動
-(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    //設定,如果要移動最後一行或者移動到最後一行,是不允許的
    if (sourceIndexPath.row == _allDataMutableArray.count - 1 || proposedDestinationIndexPath.row == _allDataMutableArray.count - 1) {
        return sourceIndexPath;
    }
    else
        return proposedDestinationIndexPath;
}
           

4.進行移動的資料操作,如果不添加這一步,就沒有修改資料源,重新加載後會複原

//移動
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    //先得到單元格上的資料
    NSString *tempStr = [self.allDataMutableArray objectAtIndex:sourceIndexPath.row];
    
    //把原位置的資料删除
    [_allDataMutableArray removeObjectAtIndex:sourceIndexPath.row];
    
    //把新資料添加到數組中對應的位置
    [_allDataMutableArray insertObject:tempStr atIndex:destinationIndexPath.row];
    
}
           

5.讓tableView重新加載資料

//重新整理資料
-(void)refreshAction:(UIBarButtonItem*)sender
{
    UITableView *tempTableView = [self.view viewWithTag:1000];
    [tempTableView reloadData];
}
           

這裡再貼上完整的代碼和效果

//
#import "RootViewController.h"

@interface RootViewController ()<UITableViewDataSource,UITableViewDelegate>

@property (nonatomic,retain)NSMutableArray* allDataMutableArray;

@end

@implementation RootViewController


- (void)viewDidLoad {
    [super viewDidLoad];
    
    //标題
    self.navigationItem.title = @"表視圖的編輯";
    
    //添加右側按鈕
    //添加按鈕
    UIBarButtonItem* addBarButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addAction:)];
    //編輯按鈕
    UIBarButtonItem* editBarButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(editAction:)];
    //添加到右側
    self.navigationItem.rightBarButtonItems = @[self.editButtonItem,addBarButton,editBarButton];
    
    //添加左側重新整理按鈕
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshAction:)];
    
    
    //初始化
    UITableView *myTableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStylePlain];
    myTableView.tag = 1000;
    
    
    //代理
    myTableView.delegate = self;
    myTableView.dataSource = self;
    
    //添加到父視圖
    [self.view addSubview:myTableView];
    
    //顯示相關的屬性
    //行高
    myTableView.rowHeight = 70;
    //分割線
    myTableView.separatorColor = [UIColor blueColor];
    myTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    //置頂視圖
    myTableView.tableHeaderView = [[UIView alloc]init];
    //置底視圖
    myTableView.tableFooterView = [[UIView alloc]init];
    
    
    //初始化數組資料
    self.allDataMutableArray = [[NSMutableArray alloc]initWithObjects:@"張三",@"李四",@"我擦",@"123",@"",@"111",@"333", nil];
    
}

//行數
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _allDataMutableArray.count;
}


//cell填充
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //cell重用機制
    
    //定義重用标示符
    static NSString* cellId = @"CELL";
    //每次需要使用單元格的是,先根據重用辨別符從重用隊列中擷取單元格,如果隊列中沒有,再進行初始化新的單元格
    //每次都會先建立一螢幕的cell,當有cell出螢幕,就會根據重用辨別符添加到對應的重用隊列中,當螢幕外的cell要進入螢幕,先從隊列中擷取,如果沒有,則初始化cell
    //當重用cell時,需要對上面的控件程式指派
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
    
    //如果從重用隊列中未擷取cell,也就是Cell為空
    if (!cell) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
        //系統提供的控件要配合不同的樣式來使用
//        cell.detailTextLabel.text = [NSString stringWithFormat:@"建立的第%d個單元格",self.index++];

    }
    
    //UITableViewCell的屬性
    
    //選中效果
    cell.selectionStyle = UITableViewCellSelectionStyleBlue;
    //輔助視圖的樣式
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    //設定左側圖檔
    cell.imageView.image = [UIImage imageNamed:@"ck.jpg"];
    //标題視圖
    cell.detailTextLabel.text = [NSString stringWithFormat:@"第%ld個cell,%ld個section",indexPath.row,indexPath.section];
    //副标題視圖
    cell.textLabel.text = _allDataMutableArray[indexPath.row];
    //為相應位置傳回定制好的單元格
    return cell;
    
}
#pragma mark -- 按鈕觸發方法
//點選添加觸發的方法
-(void)addAction:(UIBarButtonItem*)sender
{
   
}
//進入編輯狀态
-(void)editAction:(UIBarButtonItem*)sender
{
    [self setEditing:YES animated:NO];
}
//重新整理資料
-(void)refreshAction:(UIBarButtonItem*)sender
{
    UITableView *tempTableView = [self.view viewWithTag:1000];
    [tempTableView reloadData];
}


#pragma mark -- 編輯相關代理方法

//系統提供的方法按鈕會調用此方法,讓tableView處于編輯狀态
-(void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    [super setEditing:editing animated:animated];
    
    //開啟表視圖的編輯狀态
    UITableView *tempTableView = [self.view viewWithTag:1000];
    [tempTableView setEditing:editing animated:animated];
    
}
//協定設定
//确定cell是否處于編輯狀态,為NO就不能進入編輯狀态
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}


//編輯狀态的送出
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableView *tempTableView = [self.view viewWithTag:1000];
   //如果編輯模式為删除
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        //先删除資料源,也就是數組中的内容
        [_allDataMutableArray removeObjectAtIndex:indexPath.row];
        
        //再删除單元格
        //這裡要特别注意,必須先操作資料再操作單元格,不然崩的不要不要的
        [tempTableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
    }
    
    //如果編輯模式為插入
    if (editingStyle == UITableViewCellEditingStyleInsert) {
        //先插入到數組
        [_allDataMutableArray insertObject:@"新人" atIndex:indexPath.row];
        //再建立單元格
        [tempTableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
    }
}

//設定編輯的樣式
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //如果是最後一行,編輯模式為插入
    if (indexPath.row == _allDataMutableArray.count-1) {
        return UITableViewCellEditingStyleInsert;
    }
    else
        return UITableViewCellEditingStyleDelete;
}

//移動相關
//實作協定,告訴tableView是否能移動
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

//移動
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    //先得到單元格上的資料
    NSString *tempStr = [self.allDataMutableArray objectAtIndex:sourceIndexPath.row];
    
    //把原位置的資料删除
    [_allDataMutableArray removeObjectAtIndex:sourceIndexPath.row];
    
    //把新資料添加到數組中對應的位置
    [_allDataMutableArray insertObject:tempStr atIndex:destinationIndexPath.row];
    
}

//監測移動過程,限制最後一行不能移動
-(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    if (sourceIndexPath.row == _allDataMutableArray.count - 1 || proposedDestinationIndexPath.row == _allDataMutableArray.count - 1) {
        return sourceIndexPath;
    }
    else
        return proposedDestinationIndexPath;
}

@end
           

效果如下

iOS個人整理19-UITableViewController和UITableView的編輯
iOS個人整理19-UITableViewController和UITableView的編輯