【IOS 开发学习总结-OC-53】★★ios开发UI 控件——UISearchBar
UISearchBar——搜索栏
属性面板:
借鉴下老版本的属性面板说明:
属性说明:
1. options: 有多个复选框
- shows search results button: 勾选后的效果;
- shows bookmarks button: 勾选后的效果;
- shows cancel button: 勾选后的效果;
- shows scope(范围) bar: ——勾选后,会有分段条,结合scope titles设置分段的标题;
UISearchBar控件的事件处理
UISearchBar的事件触发,由该控件的委托对象处理——该对象必须实现UISearchBarDelegate 协议。
UISearchBarDelegate 协议
UISearchBarDelegate 协议中的方法:
@protocol UISearchBarDelegate <UIBarPositioningDelegate>
@optional
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar;
//判断搜索栏是否将开始编辑 return NO to not become first responder
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar;
//搜索栏开始编辑 called when text starts editing
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar;
//判断搜索栏是否将结束编辑 return NO to not resign first responder
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar;
//搜索栏结束编辑 called when text ends editing
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText;
//搜索栏文本变化后 called when text changes (including clear)
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text NS_AVAILABLE_IOS(3_0);
//判断是否将通过替换改变指定范围内的文本 选中输入的部分文本时调用 called before text changes
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar;
//搜索按钮被单击时 called when keyboard search button pressed
- (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar;
//书签按钮被单击时 called when bookmark button pressed
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar;
//取消按钮被单击时 called when cancel button pressed
- (void)searchBarResultsListButtonClicked:(UISearchBar *)searchBar NS_AVAILABLE_IOS(3_2);
//搜索结果按钮被单击时 called when search results button pressed
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope NS_AVAILABLE_IOS(3_0);
//选中的范围按钮索引(分段条上的按钮)改变时调用该方法
@end
搜索条的使用
Tip:在使用UISearchBar控件时,如果与 UITableView一起使用,注意,要将UISearchBar控件拖入UITableView页眉部分,而不是放在UITableView的上方(不重叠)。
使用示例:——UISearchBar示例 代码下载地址:
实现代码:
#import <QuartzCore/QuartzCore.h>
#import "FKViewController.h"
@implementation FKViewController
// 保存原始表格数据的NSArray对象。
NSArray * tableData;
// 保存搜索结果数据的NSArray对象。
NSArray* searchData;
bool isSearch;
- (void)viewDidLoad
{
[super viewDidLoad];
isSearch = NO;
// 初始化原始表格数据
tableData = [NSArray arrayWithObjects:@"Java工程师",
@"Android工程师",
@"HTML5工程师",
@"iOS初级工程师",
@"iOS中级工程师",
@"iOS高级工程师", nil];
// 设置UITableView控件的delegate、dataSource都是该控制器本身
self.table.delegate = self;
self.table.dataSource = self;
// 设置搜索条的delegate是该控制器本身
self.searchBar.delegate = self;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
// 如果处于搜索状态
if(isSearch)
{
// 使用searchData作为表格显示的数据
return searchData.count;
}
else
{
// 否则使用原始的tableData座位表格显示的数据
return tableData.count;
}
}
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* cellId = @"cellId";
// 从可重用的表格行队列中获取表格行
UITableViewCell* cell = [tableView
dequeueReusableCellWithIdentifier:cellId];
// 如果表格行为nil
if(!cell)
{
// 创建表格行
cell = [[UITableViewCell alloc] initWithStyle:
UITableViewCellStyleDefault
reuseIdentifier:cellId];
}
// 获取当前正在处理的表格行的行号
NSInteger rowNo = indexPath.row;
// 如果处于搜索状态
if(isSearch)
{
// 使用searchData作为表格显示的数据
cell.textLabel.text = [searchData objectAtIndex:rowNo];
}
else{
// 否则使用原始的tableData作为表格显示的数据
cell.textLabel.text = [tableData objectAtIndex:rowNo];
}
return cell;
}
// UISearchBarDelegate定义的方法,用户单击取消按钮时激发该方法
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
// 取消搜索状态
isSearch = NO;
[self.table reloadData];
}
// UISearchBarDelegate定义的方法,当搜索文本框内文本改变时激发该方法
- (void)searchBar:(UISearchBar *)searchBar
textDidChange:(NSString *)searchText // —————————— ①
{
// 调用filterBySubstring:方法执行搜索
[self filterBySubstring:searchText];
}
// UISearchBarDelegate定义的方法,用户单击虚拟键盘上Search按键时激发该方法
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar // —————————— ②
{
// 调用filterBySubstring:方法执行搜索
[self filterBySubstring:searchBar.text];
// 放弃作为第一个响应者,关闭键盘
[searchBar resignFirstResponder];
}
- (void) filterBySubstring:(NSString*) subStr // —————————— ③
{
// 设置为搜索状态
isSearch = YES;
// 定义搜索谓词
NSPredicate* pred = [NSPredicate predicateWithFormat:
@"SELF CONTAINS[c] %@" , subStr];
// 使用谓词过滤NSArray
searchData = [tableData filteredArrayUsingPredicate:pred];
// 让表格控件重新加载数据
[self.table reloadData];
}
@end
代码中的几个关键方法:
监听文本框改变的方法;过滤的方法;
监听键盘上 search 按键的单击事件;
单击搜索取消按钮时激发的方法。
UISearchDisplayController
UISearchDisplayController该控件整合UISearchBar,UITableView,内部提供了良好的封装。
该视图控制器需要充当的角色:
1. 作为 UISearchDisplayController 的委托对象;
2. 作为显示搜索结果的 UITableView 的 dataSource 对象;
3. 作为显示搜索结果的 UITableView 的 delegate 对象;
4. 作为UISearchBar对象的 delegate 对象。
所以该视图控制器需要实现上述4个对应的协议。
@interface FKViewController : UIViewController<UITableViewDataSource,
UITableViewDelegate , UISearchBarDelegate , UISearchDisplayDelegate>
@end
示例效果——下拉列表显示查询结果:
实现代码:
#import <QuartzCore/QuartzCore.h>
#import "FKViewController.h"
@interface FKViewController ()
@end
@implementation FKViewController
// 定义一个NSArray保存表格显示的原始数据
NSArray* tableData;
// 定义一个NSArray保存查询结果数据
NSArray* searchData;
bool isSearch;
- (void)viewDidLoad
{
[super viewDidLoad];
isSearch = NO;
// 初始化表格原始显示的数据
tableData = [NSArray arrayWithObjects:
@"Android工程师",
@"HTML5工程师",
@"iOS初级工程师",
@"iOS中级工程师",
@"iOS高级工程师",
@"Java入门与精通",
@"Java基础教程",
@"学习Java",
@"Objective-C基础" ,
@"Ruby入门与精通",
@"iOS开发教程" , nil];
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
// 如果处于搜索状态
if(isSearch)
{
// 使用searchData作为表格显示的数据
return searchData.count;
}
else
{
// 否则使用原始的tableData座位表格显示的数据
return tableData.count;
}
}
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* cellId = @"cellId";
// 从可重用的表格行队列中获取表格行
UITableViewCell* cell = [tableView
dequeueReusableCellWithIdentifier:cellId];
// 如果表格行为nil
if(!cell)
{
// 创建表格行
cell = [[UITableViewCell alloc] initWithStyle:
UITableViewCellStyleDefault
reuseIdentifier:cellId];
}
// 将单元格的边框设置为圆角
cell.layer.cornerRadius = 12;
cell.layer.masksToBounds = YES;
// 获取当前正在处理的表格行的行号
NSInteger rowNo = indexPath.row;
// 如果处于搜索状态
if(isSearch)
{
// 使用searchData作为表格显示的数据
cell.textLabel.text = [searchData objectAtIndex:rowNo];
}
else{
// 否则使用原始的tableData座位表格显示的数据
cell.textLabel.text = [tableData objectAtIndex:rowNo];
}
return cell;
}
// UISearchBarDelegate定义的方法,用户单击取消按钮时激发该方法
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
// 取消搜索状态
isSearch = NO;
}
// UISearchBarDelegate定义的方法,当搜索文本框内文本改变时激发该方法
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
// 调用filterBySubstring:方法执行搜索
[self filterBySubstring:searchText];
}
// UISearchBarDelegate定义的方法,用户单击虚拟键盘上Search按键时激发该方法
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
// 调用filterBySubstring:方法执行搜索
[self filterBySubstring:searchBar.text];
// 放弃作为第一个响应者,关闭键盘
[searchBar resignFirstResponder];
}
- (void) filterBySubstring:(NSString*) subStr
{
// 设置为开始搜索
isSearch = YES;
// 定义搜索谓词
NSPredicate* pred = [NSPredicate predicateWithFormat:
@"SELF CONTAINS[c] %@" , subStr];
// 使用谓词过滤NSArray
searchData = [tableData filteredArrayUsingPredicate:pred];
}
@end