iOS 自定制搜索栏,保存历史搜索
第一次写微博,目的是总结自己在项目中遇到并解决了的问题,与大家共同学习提高。另一方面是为了加深自己的印象,并留下记录,在以后的工作中方便查阅。
iOS开发中会遇到自定义的搜索栏(UITextField),将其添加到导航栏的方法试试并不难,只不过之前我没用过。
BOOL _search;
BTextField * placeHolderLabel;
NSArray * _historyArray;
UIBarButtonItem *rightBtnItem = [[UIBarButtonItem alloc]initWithTitle:@"搜索" style:UIBarButtonItemStylePlain target:self action:@selector(searchButtonClick)];
rightBtnItem.tintColor = [UIColor blackColor];
self.navigationItem.rightBarButtonItem = rightBtnItem;
[self addBackNav];
//搜索框
UIView *searchView = [[UIView alloc] initWithFrame:CGRectMake(20, 9, 434/2, 24)];
searchView.backgroundColor = [UIColor whiteColor];
searchView.layer.masksToBounds = YES;
searchView.layer.cornerRadius = 12;
//
UIImageView *searchImage = [[UIImageView alloc] init];
[searchImage setImage:[UIImage imageNamed:@"ico_search.png"]];
[searchView addSubview:searchImage];
[searchImage mas_makeConstraints:^(MASConstraintMaker *make){
make.size.mas_equalTo(CGSizeMake(14, 16));
make.rightMargin.equalTo(searchView).with.offset(-9);
make.topMargin.equalTo(searchView).with.offset(4);
}];
placeHolderLabel = [[BTextField alloc] init];
placeHolderLabel.font = GetFont(14.0f);
placeHolderLabel.placeholder =BoLocalizedString(@"cat_search_holder");
placeHolderLabel.textColor = BCOLOR_73;
[searchView addSubview:placeHolderLabel];
[placeHolderLabel mas_makeConstraints:^(MASConstraintMaker *make){
make.edges.equalTo(searchView).with.insets(UIEdgeInsetsMake(0, 2, 0, 2));//上左下右
}];
// placeHolderLabel.clearsOnBeginEditing = YES;
placeHolderLabel.clearButtonMode =UITextFieldViewModeWhileEditing;// 编辑是显示清空按钮
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doaction) name:UITextFieldTextDidChangeNotification object:placeHolderLabel];
self.navigationItem.titleView = searchView;
这样即完成了导航栏的部分。设置历史搜索原理是,用一个Bool值去记录textfiled中是否有内容,如果没有内容的话就显示历史搜索,如果有内容点击搜索进行搜索。
_productTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_productTableView.delegate = self;
_productTableView.showsVerticalScrollIndicator = NO;
_productTableView.separatorStyle = UITableViewCellEditingStyleNone;
_productTableView.backgroundColor = [UIColor whiteColor];
_productTableView.dataSource = self;
[self.view addSubview:_productTableView];
//无数据的cell不显示分割线
UIView * v = [[UIView alloc] initWithFrame:CGRectZero];
[_productTableView setTableFooterView:v];
然后实现以下搜索按钮,或者是点击了历史记录之后的方法。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (_search) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
GoodsModel *goodsModel = _proudctListArray[indexPath.row];
ProductDetailViewController *detailController = [[ProductDetailViewController alloc] initWithGoodsId:goodsModel.goods_id];
[self bPushViewController:detailController animated:YES];
}else{
if (indexPath.section==1 && indexPath.row<_historyArray.count) {
placeHolderLabel.text = _historyArray[_historyArray.count-1-indexPath.row];
[self searchButtonClick];
}
}
}
#pragma mark - tableView滑动代理
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
[placeHolderLabel resignFirstResponder];
CGFloat sectionHeaderHeight = 40;//设置你组头高度
if (scrollView.contentOffset.y<=sectionHeaderHeight&&scrollView.contentOffset.y>=0) {
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
} else if (scrollView.contentOffset.y>=sectionHeaderHeight) {
scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
}
}
#pragma mark - textFiled 搜索响应
-(void)searchButtonClick{
//取消textField第一响应者
[placeHolderLabel resignFirstResponder];
if ([placeHolderLabel.text isEqualToString:@""]) {
[self showOnlyTextDialog:@"请输入关键字"];
}else{
_search = YES;
[_productTableView setTableHeaderView:_headerView];
[self loadData];
[_productTableView reloadData];
[self SearchText:placeHolderLabel.text];
// 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法)
_productTableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadData)];
}
}
//监听textFiled是否有内容
-(void)doaction{
if ([placeHolderLabel.text isEqualToString:@""]) {
_search = NO;
[_productTableView setTableHeaderView:nil];
_productTableView.mj_footer = nil;
[self loadData];
[_productTableView reloadData];
}
}
#pragma mark - 搜索历史
-(void)SearchText :(NSString *)seaTxt
{
NSUserDefaults *userDefaultes = [NSUserDefaults standardUserDefaults];
//读取数组NSArray类型的数据
NSArray *myArray = [[NSArray alloc] initWithArray:[userDefaultes arrayForKey:@"myArray"]];
// NSArray --> NSMutableArray
NSMutableArray *searTXT = [NSMutableArray array];
searTXT = [myArray mutableCopy];
BOOL isEqualTo1,isEqualTo2;
isEqualTo1 = NO,isEqualTo2 = NO;
if (searTXT.count > 0) {
isEqualTo2 = YES;
//判断搜索内容是否存在,存在的话放到数组最后一位,不存在的话添加。
for (NSString * str in myArray) {
if ([seaTxt isEqualToString:str]) {
//获取指定对象的索引
NSUInteger index = [myArray indexOfObject:seaTxt];
[searTXT removeObjectAtIndex:index];
[searTXT addObject:seaTxt];
isEqualTo1 = YES;
break;
}
}
}
if (!isEqualTo1 || !isEqualTo2) {
[searTXT addObject:seaTxt];
}
if(searTXT.count > 15)
{
[searTXT removeObjectAtIndex:0];
}
//将上述数据全部存储到NSUserDefaults中
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:searTXT forKey:@"myArray"];
}
#pragma mark - 清空搜索历史
-(void)clickemptyBtn:(UIButton *)button{
NSString *message = NSLocalizedString(@"确定清空历史搜索吗?", nil);
NSString *cancelButtonTitle = NSLocalizedString(@"取消", nil);
NSString *otherButtonTitle = NSLocalizedString(@"确定", nil);
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert];
// Create the actions.
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
NSLog(@"取消");
}];
//确认删除
UIAlertAction *otherAction = [UIAlertAction actionWithTitle:otherButtonTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
NSUserDefaults *userDefaultes = [NSUserDefaults standardUserDefaults];
NSArray * myArray = [userDefaultes arrayForKey:@"myArray"];
NSMutableArray *searTXT = [myArray mutableCopy];
[searTXT removeAllObjects];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:searTXT forKey:@"myArray"];
[self loadData];
[self createUI];
}];
// Add the actions.
[alertController addAction:cancelAction];
[alertController addAction:otherAction];
[self presentViewController:alertController animated:YES completion:nil];
}
tableVIew 的分组,多少行,显示内容都分为两套,用Bool值去判断加载那一套。
重点说一下:
1、从用户中心读取数据的时候一定要读成不可变的数组。我最开始将其强转为可变的了,结果发现不小心把后台的数据给改动了。所以这是一个重点。
2、判断历史搜索中是否存在时,遍历数组,然后将该搜索内容删除,在添加,这样就能实现先搜索的内容在最上边显示了。
3、由于搜索历史和商品列表加的头视图,脚视图不同。在发生变化的地方都重新进行设置一下。
效果图如下: