一、效果
1. 启动程序:上面搜索栏、右边索引条
2. 点击表单元有警告框提示
3. 点击搜索栏输入内容可根据长短范围搜索
二、分析
1. 创建一个表视图,指定委托,实现表单元的显示
2. 创建一个显示搜索结果的模型,该模型也是表视图,遵循搜索结果更新协议,作为更新器
3. 创建一个搜索控制器,指定搜索结果控制器,并创建搜索栏,让搜索结果控制器实现同步更新协议,让搜索到的内容得以在搜索结果中更新
4. 在更新协议实现方法中配置搜索的逻辑
三、实现
1. 实现文件
2. Main.storyboard布局,在主控制器的视图上添加表视图,约束,指定数据源和委托。另添加一个表视图控制器,删掉表单元,修改底层类为创建的模型类
3. ViewController.m
1 // 2 // ViewController.m 3 // 8.1-实现一个简单表 4 // 5 // Created by LinKun on 16/7/19. 6 // Copyright © 2016年 Apress. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "SearchResultController.h" 11 12 static NSString *CellIdentifier = @"CellIdentifier"; 13 14 @interface ViewController () <UITableViewDataSource, UITableViewDelegate> 15 /** 表视图的输出接口 */ 16 @property (weak, nonatomic) IBOutlet UITableView *tableView; 17 /** 搜索控框制器 */ 18 @property (strong, nonatomic) UISearchController *searchController; 19 20 /** 字典数据 */ 21 @property (copy, nonatomic) NSDictionary *names; 22 /** 字典数据的键 */ 23 @property (copy, nonatomic) NSArray *keys; 24 25 @end 26 27 @implementation ViewController 28 29 #pragma mark - 30 #pragma mark 视图加载 31 - (void)viewDidLoad { 32 [super viewDidLoad]; 33 34 // 注册表单元类 35 [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier]; 36 37 // 数据的载入 38 NSString *path = [[NSBundle mainBundle] pathForResource:@"sortednames" ofType:@"plist"]; 39 self.names = [NSDictionary dictionaryWithContentsOfFile:path]; 40 // 取得字典数据的所有键 41 self.keys = [[self.names allKeys] sortedArrayUsingSelector:@selector(compare:)]; 42 43 44 // 表单元分割线颜色 45 [self.tableView setSeparatorColor:[UIColor redColor]]; 46 47 // 创建搜索结果控制器 48 SearchResultController *resultController = [[SearchResultController alloc] initWithNames:self.names keys:self.keys]; 49 // 创建搜索框控制器并指定搜索结果控制器 50 self.searchController = [[UISearchController alloc] initWithSearchResultsController:resultController]; 51 52 // 配置搜索栏:范围按钮、占位符、适配内容、安放位置 53 UISearchBar *searchBar = self.searchController.searchBar; 54 searchBar.scopeButtonTitles = @[@"All", @"Short", @"Long" ]; 55 searchBar.placeholder = @"Enter a search term"; 56 [searchBar sizeToFit]; 57 self.tableView.tableHeaderView = searchBar; 58 59 // 搜索结果更新器 60 self.searchController.searchResultsUpdater = resultController; 61 62 // 配置索引区域:常态下的背景色、点击状态下的背景色、索引字体颜色 63 self.tableView.sectionIndexBackgroundColor = [UIColor lightGrayColor]; 64 self.tableView.sectionIndexTrackingBackgroundColor = [UIColor whiteColor]; 65 self.tableView.sectionIndexColor = [UIColor blackColor]; 66 67 } 68 69 70 #pragma mark - 数据源 71 #pragma mark 分区数 72 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 73 return [self.keys count]; 74 } 75 #pragma mark 行数 76 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 77 NSString *key = self.keys[section]; 78 NSArray *value = self.names[key]; 79 return [value count]; 80 } 81 #pragma mark 表单元 82 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 83 84 // 从可重用队列申请一个可重用表单元,若有多余的表单元即分配 85 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 86 87 NSString *key = self.keys[indexPath.section]; 88 NSArray *values = self.names[key]; 89 cell.textLabel.text = values[indexPath.row]; 90 91 return cell; 92 } 93 #pragma mark 分区头部标题 94 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 95 return self.keys[section]; 96 } 97 #pragma mark 分区尾部标题 98 - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { 99 return @"尾部备注"; 100 } 101 #pragma mark 添加分区搜索索引 102 - (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView { 103 return self.keys; 104 } 105 106 107 108 109 #pragma mark - 委托 110 #pragma mark 行水平缩进 111 - (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath { 112 return 2; 113 } 114 #pragma mark 行高 115 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 116 return 40; 117 } 118 #pragma mark 分区头部高 119 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 120 return 50; 121 } 122 #pragma mark 分区尾部高 123 - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 124 return 20; 125 } 126 #pragma mark 即将选中某行 127 - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { 128 // 选中的行数据 129 NSString *key = self.keys[indexPath.section]; 130 NSArray *values = self.names[key]; 131 NSString *value = values[indexPath.row]; 132 133 NSString *message = [NSString stringWithFormat:@"You will select the \" %@ \"", value]; 134 // 警告框 135 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"willSelectRow" message:message preferredStyle:UIAlertControllerStyleAlert]; 136 UIAlertAction *action = [UIAlertAction actionWithTitle:@"Yes, I will." style:UIAlertActionStyleDefault handler:nil]; 137 [alert addAction:action]; 138 [self presentViewController:alert animated:YES completion:nil]; 139 return indexPath; 140 } 141 #pragma mark 已经选中某行 142 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 143 // 选中的行数据 144 NSString *key = self.keys[indexPath.section]; 145 NSArray *values = self.names[key]; 146 NSString *value = values[indexPath.row]; 147 148 NSString *message = [NSString stringWithFormat:@"You did select the \" %@ \" yet", value]; 149 // 警告框 150 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"didSelectRow" message:message preferredStyle:UIAlertControllerStyleAlert]; 151 UIAlertAction *action = [UIAlertAction actionWithTitle:@"Yes, I know." style:UIAlertActionStyleDefault handler:nil]; 152 [alert addAction:action]; 153 [self presentViewController:alert animated:YES completion:nil]; 154 } 155 156 @end
4. SearchResultController.h
1 // 2 // SearchResultController.h 3 // 8.1-实现一个简单表 4 // 5 // Created by LinKun on 16/8/30. 6 // Copyright © 2016年 Apress. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 #pragma mark 遵循更新搜索结果协议 11 @interface SearchResultController : UITableViewController <UISearchResultsUpdating> 12 #pragma mark 构造表视图 13 - (instancetype)initWithNames:(NSDictionary *)names keys:(NSArray *)keys; 14 15 @end
5. SearchResultController.m
1 // 2 // SearchResultController.m 3 // 8.1-实现一个简单表 4 // 5 // Created by LinKun on 16/8/30. 6 // Copyright © 2016年 Apress. All rights reserved. 7 // 8 9 #import "SearchResultController.h" 10 11 /** 表单元标识 */ 12 static NSString *CellIdentifier = @"CellIdentifier"; 13 /** 长短名字分界点 */ 14 static const NSUInteger longNameSize = 6; 15 // 搜索栏范围按钮的索引 16 static const NSUInteger shortNmaeButtonIndex = 1; 17 static const NSUInteger longNamesButtonIndex = 2; 18 19 @interface SearchResultController() 20 // 引用主界面数据 21 @property (strong, nonatomic) NSDictionary *names; 22 @property (strong, nonatomic) NSArray *keys; 23 /** 存储搜索结果数据 */ 24 @property (strong, nonatomic) NSMutableArray *filterNames; 25 26 @end 27 28 @implementation SearchResultController 29 30 - (void)viewDidLoad { 31 [super viewDidLoad]; 32 33 // 注册表单元类 34 [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier]; 35 } 36 37 #pragma mark - 初始化搜索结果视图 38 - (instancetype)initWithNames:(NSDictionary *)names keys:(NSArray *)keys { 39 // 引用主界面数据 40 if (self = [super initWithStyle:UITableViewStylePlain]) { 41 self.names = names; 42 self.keys = keys; 43 self.filterNames = [[NSMutableArray alloc] init]; 44 } 45 46 return self; 47 } 48 #pragma mark - 同步跟新搜索内容 49 - (void)updateSearchResultsForSearchController:(UISearchController *)searchController { 50 // 用户键入的搜索文本 51 NSString *searchString = searchController.searchBar.text; 52 // 用户选择的范围按钮索引 53 NSInteger buttonIndex = searchController.searchBar.selectedScopeButtonIndex; 54 55 [self.filterNames removeAllObjects]; 56 57 if (searchString.length > 0) { 58 // 定义搜索条件,满足时返回具体位置 59 NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(NSString *name, NSDictionary<NSString *,id> * _Nullable bindings) { 60 NSUInteger nameLength = name.length; 61 if ((buttonIndex == shortNmaeButtonIndex && nameLength >= longNameSize) || 62 (buttonIndex == longNamesButtonIndex && nameLength < longNameSize)) { 63 return NO; 64 } 65 NSRange range = [name rangeOfString:searchString options:NSCaseInsensitiveSearch]; 66 return range.location != NSNotFound; 67 }]; 68 // 从每个分区里找出符合的元素添加到数组里 69 for (NSString *key in self.keys) { 70 NSArray *matches = [self.names[key] filteredArrayUsingPredicate:predicate]; 71 [self.filterNames addObjectsFromArray:matches]; 72 } 73 } 74 [self.tableView reloadData]; 75 } 76 77 #pragma mark - 数据源 78 #pragma mark 行数 79 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 80 return [self.filterNames count]; 81 } 82 #pragma mark 表单元 83 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 84 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 85 cell.textLabel.text = self.filterNames[indexPath.row]; 86 return cell; 87 88 } 89 90 @end
时间: 2024-11-03 22:37:59