现在的位置: 首页 > 综合 > 正文

iOS UITableView的细致功能(滑动删除,拖动排序,添加行,搜索过滤)

2017年12月09日 ⁄ 综合 ⁄ 共 10478字 ⁄ 字号 评论关闭

对于UITableView,相信大家都并不陌生,每一个iOS app 几乎都离不开UITableViewCell,创建UITableViewCell的过程也很简单,所以也无需纪录,昨天在工作闲余时间学习了一下UITableView更细致的一些功能,这些功能使得UITableView更加强大和使用。

1、删除

删除通常有两种方式:

一是点击一个按钮后,所有的tableViewCell的最左边都出现一个红色的按钮,中间有一条横杆,点击这个按钮后右侧就会出现删除按钮

二是滑动tableViewCell,右侧会出现删除按钮。

先说第一种的实现:

创建一个UIViewController类,通过Interface Builder添加一个UItableView,为这个类添加一个数组作为成员变量,用于记录tableView的数据,头文件代码如下:

#import <UIKit/UIKit.h>

@interface ViewControllerX : UIViewController<UITableViewDataSource,UITableViewDelegate>

@property (nonatomic,retain) IBOutlet UITableView *SeanTableView;

@property (nonatomic,retain) NSMutableArray *array;

@end

在类的实现文件的ViewDidRoad方法中,加载数组数据,创建两个UIBarButtonItem类对象,即创建一个垃圾桶样式的按钮和一个➕样式的按钮,代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.array = [NSMutableArray arrayWithArray:@[@"Lin Sean",@"Lin wade",@"D wade",@"Lin James",@"CB"]];
    
    UIBarButtonItem *left = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(delete)];
    self.navigationItem.leftBarButtonItem = left;
    
    UIBarButtonItem *right = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add)];
    self.navigationItem.rightBarButtonItem = right;
}

要实现第一种删除方法,实际上是要让tableView进入编辑模式,所以垃圾筒按钮的响应函数代码如下:

- (void) delete
{
    [self.SeanTableView setEditing:YES animated:YES]; //使tableView进入编辑模式
}

到这里,点击垃圾筒按钮,就可以出现以下的情况了

     

但是,这里点击了delete按钮,也没有反应,因为还需要实现协议的一个方法

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

接着说滑动删除的方法:

这里一下子跳到滑动删除的原因,是因为只要实现了上述提到的

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath方法,tableView就能实现滑动删除了。实现这个方法的代码如下:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self.array removeObjectAtIndex:indexPath.row];
    [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

方法里首先肯定是要对数组进行删除操作,然后就是对tableView进行操作,这里没有在删除数组之后执行tableView reloadData的原因是reloadData这个方法是重新刷新整个tableView,比较耗费性能,而这里知识更改了一行数据,所以只要调用上面的第二个语句的方法,系统就会重新刷新一行的数据,这样效率会高很多。

至此,删除功能就能够完成了,可能这里还会存在很多错漏之处,但这也只是简介,更精密的代码还有待大家更具实际需求来做具体的设计。

2、添加

添加其实跟删除很类似,点击了一个添加按钮之后,所有的tableViewCell前面都会弹出一个绿色的按钮。

操作方法也是一样,当点击了➕按钮后,tableView进入编辑模式,代码如下:

- (void) add
{
    [self.SeanTableView setEditing:YES animated:YES];
}

这里就有问题了,点击删除也是进入编辑模式,点击添加也是进入编辑模式,那系统是怎样区分是删除还是添加呢?

这里就需要再实现另一个协议的方法

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath,为了区别到底是点了那个按钮,我们还需要在头文件创建一个标志变量来记录当前是那种模式。下面代码中的isInsert就是标志变量。

- (void) delete
{
    isInsert = NO;   // 加上标志记录
    [self.SeanTableView setEditing:YES animated:YES];
}

- (void) add
{
    isInsert = YES;   // 加上标志纪录
    [self.SeanTableView setEditing:YES animated:YES];
}

// 使tableView进入何种编辑模式,由这个函数的返回值进行决定
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (isInsert == YES) {
        return UITableViewCellEditingStyleInsert;
    }
    else
    {
        return UITableViewCellEditingStyleDelete;
    }
}

到这里,就可以点击垃圾桶进入删除的编辑模式,点击➕按钮就进入添加的编辑模式了。但是,这时即便进入了添加模式,点击左侧的添加按钮,会发现响应的依然是删除的功能。这事因为进入编辑模式后,系统执行何种操作,还是由上述的

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

方法决定的,这个方法的参数editingStyle就是用户判断是何种编辑模式的,所以还需要在该方法中进行判断,代码如下:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [self.array removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewAutomaticDimension];
    }
    else
    {
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
        [self.array insertObject:cell.textLabel.text atIndex:indexPath.row];
        [tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewAutomaticDimension];
    }

}

这样,一个可以大概实现增加和删除的UITableView就粗略地实现了,效果如下:

    

3.排序

其实排序,也无非是实现协议中的方法就可以实现了,只不过你以后tableViewCell后,你的数组应该如何调整,这就是逻辑问题了,需要自己去实现。

要使得tableView可以在进入编辑模式后可以排序,只要实现一下这个方法就行了,实现代码可以为空。如下:

- (void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    //这里为空,进入编辑模式后,tableView的cell也可以拖动排序,但是一般需要在这个函数里面进行一个数组元素位置的调整
}

效果如下:

这时只要长按右侧的三道杠,然后拖动cell,就可以排序了。

4、搜索过滤

搜索过滤与前面三个不同,它不属于tableView的编辑模式下进行的操作。但是在学习的过程中也接触到了,而且非常常用,所以也纪录一下

首先肯定是要添加一个搜索栏,这里为了简便,我把它添加到了navigationbar的titleView里面去,为完善搜索栏的各种功能,还需在头文件中实现UISearchBarDelegate协议,代码如下:

@interface ViewControllerX : UIViewController<UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate>

<pre name="code" class="objc">- (void)viewDidLoad {
    [super viewDidLoad];
    self.array = [NSMutableArray arrayWithArray:@[@"Lin Sean",@"Lin wade",@"D wade",@"Lin James",@"CB"]];
    
    UIBarButtonItem *left = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(delete)];
    self.navigationItem.leftBarButtonItem = left;
    
    UIBarButtonItem *right = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add)];
    self.navigationItem.rightBarButtonItem = right;
    isInsert = NO;
    
    // 在navigationBar添加一个搜索栏
    UISearchBar *sb = [[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, 60, 20)];
    sb.showsCancelButton = YES;
    self.navigationItem.titleView = sb;
    sb.delegate = self;
    
    self.searchArray = [[NSMutableArray alloc]init];
}

// 点击搜索栏cancel按钮时执行的操作
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    [searchBar resignFirstResponder]; //键盘退回
    [self.SeanTableView reloadData];
}


要实时监测searchbar输入的内容,根据内容进行表格数据的过滤,我们需要实现以下的协议方法,并创建一个新的数组和一个标志变量,用户纪录搜索的结果和判断当前是否正在搜索,代码如下:

头文件:

@interface ViewControllerX : UIViewController<UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate>
{
    bool isInsert;
    bool isSearch;
}
@property (nonatomic,retain) IBOutlet UITableView *SeanTableView;
@property (nonatomic,retain) NSMutableArray *array;
@property (nonatomic,retain) NSMutableArray *searchArray;
@end

实现文件:

// 点击搜索栏cancel按钮时执行的操作
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    isSearch = NO;
    [searchBar resignFirstResponder]; //键盘退回
    [self.SeanTableView reloadData];
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    isSearch = YES;
    if (self.searchArray.count != 0) {
        [self.searchArray removeAllObjects];
    }
    for (id sean in self.array)
    {
        if ([sean containsString:searchText]) {
            [self.searchArray addObject:sean];
            [self.SeanTableView reloadData];
        }
        else
        {
            [self.SeanTableView reloadData];
        }
    }
    
}

因为在搜索栏输入内容的时候需要tableView需要reloadData,所以需要修改代码如下:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (isSearch == YES) {
        return self.searchArray.count;
    }
    return self.array.count;
}

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *str = nil;
    if (isSearch == YES) {
        str = [self.searchArray objectAtIndex:indexPath.row];
    }
    else
    {
        str = [self.array objectAtIndex:indexPath.row];
    }
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }
    cell.textLabel.text = str;
    
    return cell;
}

至此,一个简单的搜索功能就实现了。效果如下:

头文件的完整代码如下:

#import <UIKit/UIKit.h>

@interface ViewControllerX : UIViewController<UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate>
{
    bool isInsert;
    bool isSearch;
}

@property (nonatomic,retain) IBOutlet UITableView *SeanTableView;

@property (nonatomic,retain) NSMutableArray *array;

@property (nonatomic,retain) NSMutableArray *searchArray;

@end

实现文件的完整代码如下:

#import "ViewControllerX.h"

@interface ViewControllerX ()

@end

@implementation ViewControllerX

- (void)viewDidLoad {
    [super viewDidLoad];
    self.array = [NSMutableArray arrayWithArray:@[@"Lin Sean",@"Lin wade",@"D wade",@"Lin James",@"CB"]];
    
    UIBarButtonItem *left = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(delete)];
    self.navigationItem.leftBarButtonItem = left;
    
    UIBarButtonItem *right = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add)];
    self.navigationItem.rightBarButtonItem = right;
    isInsert = NO;
    
    // 在navigationBar添加一个搜索栏
    UISearchBar *sb = [[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, 60, 20)];
    sb.showsCancelButton = YES;
    self.navigationItem.titleView = sb;
    sb.delegate = self;
    
    self.searchArray = [[NSMutableArray alloc]init];
}

// 点击搜索栏cancel按钮时执行的操作
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    isSearch = NO;
    [searchBar resignFirstResponder]; //键盘退回
    [self.SeanTableView reloadData];
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    isSearch = YES;
    if (self.searchArray.count != 0) {
        [self.searchArray removeAllObjects];
    }
    for (id sean in self.array)
    {
        if ([sean containsString:searchText]) {
            [self.searchArray addObject:sean];
            [self.SeanTableView reloadData];
        }
        else
        {
            [self.SeanTableView reloadData];
        }
    }
    
}

- (void) delete
{
    isInsert = NO;   // 加上标志记录
    [self.SeanTableView setEditing:YES animated:YES];
}

- (void) add
{
    isInsert = YES;   // 加上标志纪录
    [self.SeanTableView setEditing:YES animated:YES];
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (isInsert == YES) {
        return UITableViewCellEditingStyleInsert;
    }
    else
    {
        return UITableViewCellEditingStyleDelete;
    }
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [self.array removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewAutomaticDimension];
    }
    else
    {
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
        [self.array insertObject:cell.textLabel.text atIndex:indexPath.row];
        [tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewAutomaticDimension];
    }

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (isSearch == YES) {
        return self.searchArray.count;
    }
    return self.array.count;
}

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *str = nil;
    if (isSearch == YES) {
        str = [self.searchArray objectAtIndex:indexPath.row];
    }
    else
    {
        str = [self.array objectAtIndex:indexPath.row];
    }
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }
    cell.textLabel.text = str;
    
    return cell;
}

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

@end

抱歉!评论已关闭.