UITableView表格操作

UITableView【表格视图】

UITableView是表格视图,是UIScrollView的子类,非常重要。

一、表格视图常用属性

 1、基本属性方法

创建一个tableView

    //    UITableViewStylePlain, //扁平风格的        

    //    UITableViewStyleGrouped //跟系统设置风格是一样的   分组风格   

UITableView *tableView = [[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStyleGrouped];

 表格的背景颜色

    tableView.backgroundColor = [UIColor orangeColor];

 如果根视图是导航视图控制器,则需要取消导航控制器对布局的影响

方法一:

        //让导航条透明(原点坐标是从屏幕左上角开始的),scrollview(子类) 正常显示

        self.automaticallyAdjustsScrollViewInsets = NO;

        CGRect tableViewFrame = tableView.frame ;

        tableViewFrame.origin.y += 64;

        tableViewFrame.size.height -= 64;

        tableView.frame = tableViewFrame;

 方法二:    

        //取消导航视图控制器 对布局(第一个子视图是UIScrollview的子类)的影响

        // 设置UIRectEdgeNone 之后,你发发现 self.view 零点是导航栏下边开始的

        self.edgesForExtendedLayout = UIRectEdgeNone;

        CGRect tableViewFrame = tableView.frame ;

        tableViewFrame.size.height -= 64;

        tableView.frame = tableViewFrame;

分割线的类型

UITableViewCellSeparatorStyleNone, 没有(一般情况下,做一些比较复杂cell 分割线是不显示,自己可以定制一条分割线)

    UITableViewCellSeparatorStyleSingleLine,细线

    UITableViewCellSeparatorStyleSingleLineEtched 没有

    tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;

 分割线颜色

    tableView.separatorColor = [UIColor redColor];

  

设置分割线边界的

    tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0);

tableview 的头视图 和 尾视图   是一个UIView类型的

tableView.tableHeaderView

tableView.tableFooterView

2、数据代理方法

UITableViewDataSource 数据源协议,告诉tableView 要显示多少行和每一行要显示内容

设置代理

 tableView.dataSource = self;

代理方法必须实现的方法  (行数和内容)

//设置第section组的行数

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

   return   [self.dataSource[section] count];

}

//设置cell 内容(行内容)

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  //创建一个cell

    //第一个参数 cell的风格

    //第二个参数 唯一标示符 用来复用cell的,怎么复用呢,只创建比我们能看到屏幕上cell 多一点,每当我们下滑动的时候,会多的cell 拿过来用。系统会创建一个复用的队列,每当需要创建cell的时候,会先去队列里面找有没有可用的cell(cellID是一样的),如果有可用的,就拿过来用,如果没有可用的cell,就直接创建一个。

     //先检测复用队列,有没有可以用cell

    static NSString *cellID = @"cellID";

    //检测对应id 有没有对应的可用cell

    UITableViewCell *reuseCell = [tableView dequeueReusableCellWithIdentifier:cellID];

    if (reuseCell == nil) {

  不存在可以复用cell,就去创建一个

        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];

    }

     cell自带了一个label 和imageView

    cell的类型:

       UITableViewCellStyleDefault   有两个label

       UITableViewCellStyleValue1,(系统的设置风格)

       UITableViewCellStyleValue2,(跟系统联系人的风格相似)(图片不会显示)

  UITableViewCellStyleSubtitle

     NSString *name =  self.dataSource[indexPath.section][indexPath.row];

    cell.textLabel.text = name;

//设置图片

    cell.imageView.image = [UIImage imageNamed:@"2"];  

//详细信息label

    cell.detailTextLabel.text = @"详细信息";

//cell的内容视图(放自定义控件)

    cell.contentView.backgroundColor = [UIColor cyanColor];

//指示附加视图

    cell.accessoryType = UITableViewCellAccessoryDetailButton;

//自己定制附加视图

 cell.accessoryView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"3"]];

 附件视图被点中会调用协议方法 

  - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath;

     

//点击cell之后的风格

//    UITableViewCellSelectionStyleNone,

//    UITableViewCellSelectionStyleBlue,

//    UITableViewCellSelectionStyleGray,

//    UITableViewCellSelectionStyleDefault 

    cell.selectionStyle = UITableViewCellSelectionStyleGray;

    //设置选中的背景视图

    UIView *selectedView = [[UIView alloc]init];

    selectedView.backgroundColor = [UIColor blueColor];

    cell.selectedBackgroundView = selectedView;

    

    return cell;

}

//设置tableview 有多少组

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

    return self.dataSource.count;

}

//分组的 index title

- (nullable NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView {

    

    return @[@"a",@"b",@"b",@"c",@"c"];

}

//改变 点击index title 所 跳到的组

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {

    if ([title isEqualToString:@"a"]) {

        return 4;

    }

    return index;

}

3、本身代理方法 

设置行、头视图,尾视图的高

设置头视图和尾视图    返回值UIView

设置头视图和尾视图的title  返回NSString

选中某一行

////设置组头

- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

    UIView *headerSectionView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];

    headerSectionView.backgroundColor = [UIColor yellowColor];

    return headerSectionView;

}

////设置组尾视图

- (UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {

    UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];

    view.backgroundColor = [UIColor greenColor];

    return view;

}

////设置组头高度

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

    return 100;

}

////组尾高度

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {

    return 100;

}

//设置组头title //粘性表头  tableview 的风格 必须是plain,组头组尾视图不能设置,系统默认的头尾视图。

- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;   

- (nullable NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;

//选了某一行

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

   

    //可以选中进去之后,在出来,cell 就不被选中

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    

   将选中的行的信息在另一个视图显示

    DetailViewController *dvc = [[DetailViewController alloc]init];

    //点击的那一行的 名字

   NSString *name =  self.dataSource [indexPath.section][indexPath.row];

    dvc.name = name;

    [self.navigationController pushViewController:dvc animated:YES];

    

}

代理

tableView.delegate  = self;

// tableview 是继承于UIScrollview·的,所以UIscrollView的协议方法,tableView都能用

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

    NSLog(@"scrollViewDidScroll");

}

二、表格视图的基本操作

1、      为了方便操作,创建了表格的基类,在基类中实现以后必须要用的方法(行,内容)和属型,必须在.h中声明属性和非类方法(后续需要不断使用的方法)

@property (nonatomic, strong) UITableView *tableView;

@property (nonatomic, strong) NSMutableArray *dataSource;

/**

 *  创建数据源 子类取实现 需要重写

 */

- (void)createDataSource;

  

 2、操作表格时需实现协议中的方法 对表格  提交编辑和 设置编辑(多行删除除外)

****************************************************************添加一行 AddCellViewController

  (1)  首先,重写数据源    数据源单独作为一个类,创建多种数据源

- (void)createDataSource {

    self.dataSource = [DataSourceStore createOPDataSource];

}

(2)根据数据源中数据存储的形式重写类方法cell

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *reusableCell = [super tableView:tableView cellForRowAtIndexPath:indexPath];

    reusableCell.textLabel.text = [NSString stringWithFormat:@"重写%@",self.dataSource[indexPath.row]]  ;

    

    return reusableCell;  

}

(3)编辑表格

//编辑的风格

//    UITableViewCellEditingStyleNone,

//    UITableViewCellEditingStyleDelete,

//    UITableViewCellEditingStyleInsert

// 提交编辑

//类方法

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    if (editingStyle == UITableViewCellEditingStyleInsert) {

    

        //首先要在数据源添加一个数据

        [self.dataSource insertObject:@"添加的" atIndex:indexPath.row];

        //刷新全部的数据

        //[self.tableView reloadData];

        //插入一行 刷新一行

        [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 

        

    }

    else if (editingStyle == UITableViewCellEditingStyleDelete){

        NSLog(@"删除");

    }

}

//设置编辑风格

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

    return UITableViewCellEditingStyleInsert;

}

****************************************************************删除一行  RemoveViewController

(1)  首先,重写数据源

(2 )编辑表格

//提交编辑

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    if (editingStyle == UITableViewCellEditingStyleDelete) {

        

        //先删除数据源的某个元素

        [self.dataSource removeObjectAtIndex:indexPath.row];

        [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

    }

}

//设置编辑类型

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

    return UITableViewCellEditingStyleDelete;

}

//iOS8的新属性,自定义左滑cell按钮

- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {

    //行动作

//    UITableViewRowActionStyleDefault = 0,

//    UITableViewRowActionStyleDestructive = UITableViewRowActionStyleDefault,

//    UITableViewRowActionStyleNormal

    UITableViewRowAction *action1 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"置顶" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {

        NSLog(@"点击置顶按钮");

    }];

    

    UITableViewRowAction *action2 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {

        NSLog(@"点击删除按钮");

    }];

    

    return @[action1,action2];

}

**********************************************************************删除多行不需要编辑表格和提交编辑,需要直接重写item“编辑”的触发事件

(1)  首先,重写数据源

(2 )重写导航栏的“编辑”item的触发事件

//设置编辑

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

    return UITableViewCellEditingStyleDelete | UITableViewCellEditingStyleInsert;

}

//用两个协议方法来记录选中和撤销

//撤销选中行

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {

    

}

//选中行

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    //只有是编辑模式的时候我们才去几乎选中的行

    if (tableView.isEditing) {

    }

    //有一个专门记录选中的行数

  //  tableView.indexPathsForSelectedRows;

  //  NSLog(@"%ld",tableView.indexPathsForSelectedRows.count);

    

}

- (void)itemPressed:(UIBarButtonItem*)item {

    NSLog(@"强制重写");

    if (self.tableView.isEditing) {

       //在这里处理多选删除

        //先删除数据源

        //多选删除的时候必须要倒序删除

        //1、先把数组里边的元素排序

        NSArray *resultArray = [self.tableView.indexPathsForSelectedRows sortedArrayUsingSelector:@selector(compare:)];

        //按照数组里边的内容 类型 compare: 方法进行排序,一般compare:都是从小到大排序

        //逆序数组,首先逆序枚举,然后取出所有得元素

        NSArray *reverseArray = [[resultArray reverseObjectEnumerator] allObjects];

        

        for (NSIndexPath *indexpath in reverseArray) {

            [self.dataSource removeObjectAtIndex:indexpath.row];

        }

        //刷新界面

        [self.tableView deleteRowsAtIndexPaths:self.tableView.indexPathsForSelectedRows withRowAnimation:UITableViewRowAnimationAutomatic];

        // self.tableView.editing = NO;

        //带有动画效果

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

    }

    else {

        //self.tableView.editing = YES;

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

    }

}

***********************************************************************折叠FoldViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    //初始化数组状态,设置section全是关闭

    self.sectionsState = [NSMutableArray arrayWithObjects:@0,@0,@0,@0, nil];

    // Do any additional setup after loading the view.

}

- (void)createDataSource {

    self.dataSource = [DataSourceStore createFlodDataSource];

}

//两个重要的协议

//行数

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    NSNumber *state = self.sectionsState[section];

    //如果是关闭的,返回0;

    if (state.intValue == 0) {

        return 0;

    }

    else{

        //只要是打开的就返回数组里面的元素个数

        return [self.dataSource[section] count];

    }

    

}

//内容

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    

    static NSString *cellID = @"cellID";

    UITableViewCell *reusableCell = [tableView dequeueReusableCellWithIdentifier:cellID];

    if (reusableCell == nil) {

        reusableCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];

    }

    reusableCell.textLabel.text = self.dataSource[indexPath.section][indexPath.row];

    

    return reusableCell;

}

//组数

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

    return [self.dataSource count];

}

//设置组头

- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

    

    UIButton *headerView = [UIButton buttonWithType:UIButtonTypeSystem];

    headerView.frame = CGRectMake(0, 0, self.view.frame.size.width, 44);

    [headerView setTitle:@"我的好友" forState:UIControlStateNormal];

    headerView.backgroundColor = [UIColor greenColor];

    [headerView addTarget:self action:@selector(headerViewPressed:) forControlEvents:UIControlEventTouchUpInside];

    headerView.tag = section + 100;

    return headerView;

}

- (void)headerViewPressed:(UIButton*)sender {

    

    NSInteger section = sender.tag - 100;

    BOOL state = [self.sectionsState[section] boolValue];

    

    //修改数据源

    NSNumber *currentState = state?@0:@1;

    

    //如果是关着的就设置现在的状态为开,反之一样

    [self.sectionsState replaceObjectAtIndex:section withObject:currentState];

    //刷新对应的section

    [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationAutomatic];

    //NSLog(@"点击了%ld头视图",section);

}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

    return 44.0;

}

****************************************************************** 移动  MoveViewController

(1)  首先,重写数据源

(2 )设置行可以移动

//让表格可以移动

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {

    return YES;

}

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

    return  UITableViewCellEditingStyleNone;

}

(3 )移动表格的行

//移动表格的协议方法

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {

    //改变数据源

    [self.dataSource exchangeObjectAtIndex:sourceIndexPath.row withObjectAtIndex:destinationIndexPath.row];

}

*******************************************************************搜索 SearchViewController

首先必须遵守的两个协议UISearchBarDelegate,UISearchDisplayDelegate

为了方便使用,设置三个属性

@property (nonatomic, strong) UISearchBar *searchBar;  搜索栏

@property (nonatomic, strong) UISearchDisplayController *searchDC; 显示搜索结果

@property (nonatomic, strong) NSMutableArray *resultArray;  存放搜索的结果

(1)首先,创建视图,将搜索栏添加到表格的   表头  并设置协议的代理

- (void)createView {

    _searchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44.0)];

    _searchBar.placeholder = @"请输入";

    self.tableView.tableHeaderView = _searchBar;

    _searchDC = [[UISearchDisplayController alloc]initWithSearchBar:_searchBar contentsController:self];

    _searchDC.searchResultsDelegate = self;

    _searchDC.searchResultsDataSource= self;

}

(2)创建数据源

(3)实现tableView必须实现的两个协议方法(重写行数和内容)

//行数

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    if (tableView == self.tableView) {

        return [self.dataSource count];

    }

    else{

        //说明是searchBar的tableView

        

//        //拿到搜索结果

//        //谓词搜索

//        //查询后面的字符串是否包含搜索内容

//        NSPredicate *pd = [NSPredicate predicateWithFormat:@"self contains[cd]%@",_searchBar.text];

//        //在我们的数据源查找

//        NSArray *array1 = [self.dataSource filteredArrayUsingPredicate:pd];

//        self.resultArray = [NSMutableArray arrayWithArray:array1];

//        

//        return self.resultArray.count ;

        

        

        //第二种方法  ios8以后才能用

        self.resultArray = [NSMutableArray new];

        for (NSString *item in self.dataSource) {

           BOOL contains = [item containsString:_searchBar.text];

            if (contains) {

                //只要包含 就添加到结果里边

                [_resultArray addObject:item];

            }

        }

        return self.resultArray.count;

    }

}

//搜索内容

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *cellID = @"cellID";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];

    if (cell == nil) {

        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];

    }

    if (tableView == self.tableView) {

        cell.textLabel.text = self.dataSource[indexPath.row];

    }

    else {

        //就是我们的searchBar的tableView视图

        cell.textLabel.text = self.resultArray[indexPath.row];

    }

    return cell;

}

原文地址:https://www.cnblogs.com/jiang-xiao-yan/p/5952479.html