表视图搜索栏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了表视图搜索栏相关的知识,希望对你有一定的参考价值。

一、效果

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

 

以上是关于表视图搜索栏的主要内容,如果未能解决你的问题,请参考以下文章

表视图中的搜索栏失败

滚动表视图然后突然单击搜索栏会导致应用程序崩溃?

当搜索栏处于活动状态时,快速表视图被锁定

表视图搜索栏

是否可以在分组表视图上方放置隐藏搜索栏?

如何正确配置添加到现有表视图控制器的搜索栏?