多选删除,搜索
*****多选删除*****
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
//2个一起返回,就是多选删除模式
return UITableViewCellEditingStyleDelete | UITableViewCellEditingStyleInsert;
}
思路
【一】,设一个可变数组arr,当处于编辑状态时每选中一个cell就添加一个数据到arr中,反选一个就删除一个
【二】,在编辑方法中清除arr中的内容
- (void)customEditMethod
{//自定义按钮实现编辑方法时,需要设置一个bool型成员变量
_isEditing = !_isEditing;
[_tableView setEditing:_isEditing animated:YES];
}
self.navigationItem.leftBarButtonItem = self.editButtonItem;
//使用系统自带的编辑按钮时必须让父类重载编辑方法
-(void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
[myTableView setEditing:editing animated:animated];
}
【三】,设一个button或其它有点击事件的view,在点击事件中将arr里的对象从数据源中删除,然后重载tableView
*****搜索*****
【一,索引】
//为tableView设置索引
//NSArray (存放索引标题的数组)
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
//UITableViewIndexSearch 系统内置的字符串,会显示成一个放在镜
NSMutableArray *arr = [[NSMutableArray arrayWithObject:UITableViewIndexSearch];
//do something
return arr;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{//因为索引的前面加了个搜索小图标,所以需要重写这个方法点击的时候要返回的数要-1
return index-1;
}
【二,搜索】
//搜索条被激活时会自动出现在导航条上
一,创建UISearchBar和UISearchDisplayController
_sb = [[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
_tv.tableHeaderView = _sb;
_sdc = [[UISearchDisplayController alloc]initWithSearchBar:_sb contentsController:self];
_sdc.delegate = self;
_sdc.searchResultsDelegate = self;
_sdc.searchResultsDataSource = self;
二,【UISearchDisplayDelegate】
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{//在搜索框里输入的时候触发
[_resultArr removeAllObjects];
for (NSMutableArray *marr in _dataArr) {
for (NSString *str in marr) {
NSRange ran = [str rangeOfString:searchString];
if (ran.length) {
[_resultArr addObject:str];
}
}
}
return YES;
}
三,搜索结果展示会自动创建一个新的tableView,用的也是tableView的代理,所以需要在所有的代理中判断现在是搜索结果,还是原来的tableview
折叠,展开
思路:
1,设置一个可变数组记录每一分区的展开状态,点击每一行的headView的时候就改变这一分区的展开状态,
然后重载这一段
[_tv reloadSections:[NSIndexSet indexSetWithIndex:sender.tag-1000] withRowAnimation:UITableViewRowAnimationAutomatic];
2,在numberOfRowsInSection里判断展开状态,如果是展开状态就正常显示,如果是折叠状态就返回0
#import "FirstViewController.h"
#import "DogModel.h"
@interface FirstViewController () <UITableViewDataSource, UITableViewDelegate>
{
NSMutableArray *_dataArr;
UITableView *_myTableView;
//存放准备删除的数据
NSMutableArray *_deleteArr;
//删除按钮
UIBarButtonItem *_deleteItem;
}
@end
@implementation FirstViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor redColor];
self.automaticallyAdjustsScrollViewInsets = NO;
_deleteArr = [[NSMutableArray alloc] init];
[self createData];
[self createUI];
}
- (void)createData
{
_dataArr = [[NSMutableArray alloc] init];
for (int i = 0; i<15; i++) {
DogModel *dm = [[DogModel alloc] init];
dm.name = [NSString stringWithFormat:@"狗%d",i];
dm.age = [NSString stringWithFormat:@"%d岁",arc4random_uniform(8)];
dm.length = [NSString stringWithFormat:@"%d",[dm.age intValue]+5];
[_dataArr addObject:dm];
}
}
- (void)createUI
{
_myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 70, 320, 410)];
_myTableView.delegate = self;
_myTableView.dataSource = self;
[self.view addSubview:_myTableView];
//self.editButtonItem 系统自带的编辑按钮
self.navigationItem.leftBarButtonItem = self.editButtonItem;
//删除按钮
_deleteItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(deleteClick)];
}
- (void)deleteClick
{
//从数据源里删除另外一个数组中所有的对象
[_dataArr removeObjectsInArray:_deleteArr];
//数据源改变以后刷新一下tv
[_myTableView reloadData];
}
//self.editButtonItem的点击事件
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
//这个事件里必须重载父类方法,(类似viewDidLoad)
[super setEditing:editing animated:YES];
//editing每次点击的时候会自动改变
//设置tv的编辑状态
[_myTableView setEditing:editing animated:YES];
//编辑状态发生改变的时候清空待删除数组
[_deleteArr removeAllObjects];
//根据编辑状改变删除按钮的显示状态
if (editing) {
[self.navigationItem setRightBarButtonItem:_deleteItem animated:YES];
} else {
[self.navigationItem setRightBarButtonItem:nil animated:YES];
}
}
#pragma mark - tableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _dataArr.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 80;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ident = @"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ident];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ident];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 10, 200, 60)];
label.backgroundColor = [UIColor yellowColor];
label.numberOfLines = 0;
label.tag = 100;
//往cell上新建view的时候,需要加在contentView上
[cell.contentView addSubview:label];
}
//如果想在cell上添加一些子view,需要在cell被alloc的时候添加
//然后在复用的时候修改里面的内容。
//严禁在cell复用的时候创建view
//找到cell对应的数据模型
DogModel *dm = [_dataArr objectAtIndex:indexPath.row];
//根据tag值,找到当前cell里的label
UILabel *label = (UILabel *)[cell.contentView viewWithTag:100];
label.text = dm.name;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{//cell的点击事件
//判断tv是否处在编辑状态
if (tableView.editing) {
//将cell对应的数据模型添加到待删除数组中
[_deleteArr addObject:[_dataArr objectAtIndex:indexPath.row]];
} else {
//如果tv是正常状态,那么该干嘛干嘛(push,或者打印...)
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{//cell被反选时调用
//从待删除数组中,把对应的数据模型拿出去
[_deleteArr removeObject:[_dataArr objectAtIndex:indexPath.row]];
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{//设置编辑风格
return UITableViewCellEditingStyleDelete | UITableViewCellEditingStyleInsert;
}
#import <Foundation/Foundation.h>
@interface DogModel : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *age;
@property (nonatomic, copy) NSString *length;
@end
#import "FirstViewController.h"
@interface FirstViewController () <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate>
{
NSMutableArray *_dataArr;
UITableView *_myTableView;
//搜索条
UISearchBar *_sb;
//搜索控制器
UISearchDisplayController *_sdc;
//保存搜索结果的数组
NSMutableArray *_resultArr;
}
@end
@implementation FirstViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.automaticallyAdjustsScrollViewInsets = NO;
self.view.backgroundColor = [UIColor redColor];
[self createData];
[self createUI];
}
- (void)createData
{
_dataArr = [[NSMutableArray alloc] init];
for (int i = 'a'; i<='z'; i++) {
NSMutableArray *arr = [NSMutableArray array];
for (int j = 0; j<=9; j++) {
NSString *str = [NSString stringWithFormat:@"%c%d",i,j];
[arr addObject:str];
}
[_dataArr addObject:arr];
}
}
- (void)createUI
{
_myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 70, 320, 410)];
_myTableView.delegate = self;
_myTableView.dataSource = self;
[self.view addSubview:_myTableView];
//设置当前tv中索引条里文字的颜色,背景色
_myTableView.sectionIndexColor = [UIColor whiteColor];
_myTableView.sectionIndexBackgroundColor = [UIColor grayColor];
_myTableView.sectionIndexTrackingBackgroundColor = [UIColor redColor];
_resultArr = [[NSMutableArray alloc] init];
//创建搜索条
_sb = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
//把搜索条设置为tv的头
_myTableView.tableHeaderView = _sb;
//创建搜索控制器,关联sb和vc
_sdc = [[UISearchDisplayController alloc] initWithSearchBar:_sb contentsController:self];
//当sb里的文字发生改变的时候,触发方法的代理
_sdc.delegate = self;
//搜索控制器自带tableView,也需要设置代理
_sdc.searchResultsDataSource = self;
_sdc.searchResultsDelegate = self;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{//当搜索条里的文字发生的改变的时候,搜索控制器会调代理的这个方法
//开始之前清空搜索结果的数组
[_resultArr removeAllObjects];
//深度遍历数据源
for (NSArray *arr in _dataArr) {
for (NSString *str in arr) {
NSRange range = [str rangeOfString:searchString];
if (range.length) {
[_resultArr addObject:str];
}
}
}
return YES;
}
#pragma mark - tableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (tableView != _myTableView) {
//如果响应代理方法的tv不是我自己创建的,那么他一定是搜索控制器创建的
//用来展示搜索结果的
//本案中,搜索结果只显示成一个分段
return 1;
}
return [_dataArr count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView != _myTableView) {
//搜索结果页的行数
return [_resultArr count];
}
return [[_dataArr objectAtIndex:section] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (tableView != _myTableView) {
return @"搜索结果";
}
return [NSString stringWithFormat:@"%c",'A'+section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = @"cellId";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
if (tableView != _myTableView) {
cell.textLabel.text = [_resultArr objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [[_dataArr objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
}
return cell;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{//设置索引条
if (tableView != _myTableView) {
return nil;
}
//UITableViewIndexSearch 自带的一个字符串,显示出来就是放大镜
NSMutableArray *arr = [NSMutableArray arrayWithObject:UITableViewIndexSearch];
for (int i = 'A'; i<='Z'; i++) {
[arr addObject:[NSString stringWithFormat:@"%c",i]];
}
return arr;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{//索引条的点击事件,参数index代表了点击的是第几个索引
//返回值是想要跳到第几段
if (!index) {
//如果点击的是放大镜,直接复位
_myTableView.contentOffset = CGPointZero;
}
return index-1;
}
#import "FirstViewController.h"
@interface FirstViewController () <UITableViewDataSource, UITableViewDelegate>
{
NSMutableArray *_dataArr;
UITableView *_myTableView;
//用来记录cell的展开状态
NSMutableArray *_isOpen;
}
@end
@implementation FirstViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.automaticallyAdjustsScrollViewInsets = NO;
self.view.backgroundColor = [UIColor redColor];
[self createData];
[self createUI];
}
- (void)createData
{
_dataArr = [[NSMutableArray alloc] init];
_isOpen = [[NSMutableArray alloc] init];
for (int i = 'a'; i<='z'; i++) {
NSMutableArray *arr = [NSMutableArray array];
for (int j = 0; j<=9; j++) {
NSString *str = [NSString stringWithFormat:@"%c%d",i,j];
[arr addObject:str];
}
[_dataArr addObject:arr];
[_isOpen addObject:[NSNumber numberWithBool:NO]];
}
}
- (void)createUI
{
_myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 70, 320, 410)];
_myTableView.delegate = self;
_myTableView.dataSource = self;
[self.view addSubview:_myTableView];
}
#pragma mark - tableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [_dataArr count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([[_isOpen objectAtIndex:section] boolValue]) {
return [[_dataArr objectAtIndex:section] count];
}
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 30;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
btn.frame = CGRectMake(0, 0, 320, 30);
btn.backgroundColor = [UIColor greenColor];
[btn setTitle:[NSString stringWithFormat:@"%c",'A'+section] forState:UIControlStateNormal];
btn.tag = 1000+section;
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
return btn;
}
- (void)btnClick:(UIButton *)sender
{
//找到对应的展开状态
BOOL isO = [[_isOpen objectAtIndex:sender.tag-1000] boolValue];
//修改
[_isOpen replaceObjectAtIndex:sender.tag-1000 withObject:[NSNumber numberWithBool:!isO]];
//重载某个分段,NSIndexSet数字集合,理解成专门存放数字的数组
[_myTableView reloadSections:[NSIndexSet indexSetWithIndex:sender.tag-1000] withRowAnimation:UITableViewRowAnimationFade];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = @"cellId";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
cell.textLabel.text = [[_dataArr objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
return cell;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{//设置索引条
NSMutableArray *arr = [NSMutableArray array];
for (int i = 'A'; i<='Z'; i++) {
[arr addObject:[NSString stringWithFormat:@"%c",i]];
}
return arr;
}