iOS

前言

	NS_CLASS_DEPRECATED_IOS(3_0, 8_0, "UISearchDisplayController has been replaced with UISearchController")
	@interface UISearchDisplayController : NSObject
	
	@available(iOS, introduced=3.0, deprecated=8.0, message="UISearchDisplayController has been replaced with 
		UISearchController")
	public class UISearchDisplayController : NSObject


	NS_CLASS_AVAILABLE_IOS(8_0) @interface UISearchController : UIViewController 
		<UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>
	@available(iOS 8.0, *) 	 public class UISearchController : UIViewController, 
		UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning
  • 在 iOS 8.0 以上版本中, 我们可以使用 UISearchController 来非常方便地在 UITableView 中添加搜索框. 而在之前版本中, 我们还是必须使用 UISearchDisplayController + UISearchBar 的组合方式.

  • 我们创建的 tableView 和搜索控制器创建的 tableView 都会走代理方法,需要在代理方法中判断响应代理方法的 tableView 是哪一个,如果响应代理方法的 tableView 不是我创建的,说明一定是搜索控制器创建的。在 iOS 8.0 以下版本中需使用 tableView == myTableView 判断,在 iOS 8.0 以上版本中需使用 mySearchController.active 判断。

1、搜索框的创建

1.1 在 iOS 8.0 以下版本中

  • Objective-C

    • 遵守协议 UISearchDisplayDelegate

    • 搜索结果数组初始化

      	// 声明搜索结果存放数组
      	@property(nonatomic, retain)NSMutableArray *mySearchResultArray;
      
      	// 初始化搜索结果存放数组
      	mySearchResultArray = [[NSMutableArray alloc] init];
      
    • searchDisplayController 初始化

      	// 声明搜索控制器,自带一个表格视图,用来展示搜索结果,必须设置为全局变量
      	@property(nonatomic, retain)UISearchDisplayController *mySearchDisplayController;
      	
      	// 实例化搜索条
      	UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
      	
      	// 实例化搜索控制器对象
      	mySearchDisplayController = [[UISearchDisplayController alloc] 
      	                                            initWithSearchBar:searchBar 
      	                                           contentsController:self];	
      	// 设置搜索控制器的代理
      	mySearchDisplayController.delegate = self;
      
      	// 为搜索控制器自带 tableView 指定代理
      	mySearchDisplayController.searchResultsDelegate = self;
      	mySearchDisplayController.searchResultsDataSource = self;
      
      	// 将搜索条设置为 tableView 的表头
      	myTableView.tableHeaderView = searchBar;
      
    • UISearchDisplayDelegate 协议方法

      	// 更新搜索结果
      	/*
      		只要搜索框的文字发生了改变,这个方法就会触发。searchString 为搜索框内输入的内容。
      	*/
      	- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
      	
      		// 清空上一次搜索的内容
          	[mySearchResultArray removeAllObjects];
          
          	// 将搜索的结果存放到数组中
          	for (NSArray *subArray in myDataArray) {
      			for (NSString *str in subArray) {
                  
      				NSRange range = [str rangeOfString:searchString];
                  
      				if (range.length) {
      					[mySearchResultArray addObject:str];
      				}
      			}
          	}
          	return YES;
      	}
      
    • UITableView 协议方法

      	// 设置分段头标题
      	- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
      
          	if (tableView == myTableView) {
      			return [NSString stringWithFormat:@"%c", (char)('A' + section)];
          	}
          	return @"搜索结果";
      	}
      
      	// 设置分段数
      	- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
          
          	if (tableView == myTableView) {
          		return myDataArray.count;
          	}
          	return 1;
      	}
      
      	// 设置行数
      	- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
      
      		if (tableView == myTableView) {
      			return [[myDataArray objectAtIndex:section] count];
      		}
      		return mySearchResultArray.count;
      	}
      
      	// 设置每段显示的内容
      	- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
          
      		UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"testIdentifier"];
          
      		if (!cell) {
      			cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"testIdentifier"];
      		}
          
      		if (tableView == myTableView) {
      			cell.textLabel.text = [[myDataArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
      		}
      		else {
      			cell.textLabel.text = [mySearchResultArray objectAtIndex:indexPath.row];
      		}
          
      		return cell;
      	}
      
  • Swift

    • 遵守协议 UISearchDisplayDelegate

    • 搜索结果数组初始化

      	// 初始化搜索结果存放数组
      	var mySearchResultArray:[String] = Array()
      
    • searchDisplayController 初始化

      	// 声明搜索控制器,自带一个表格视图,用来展示搜索结果,必须设置为全局变量
      	var mySearchDisplayController:UISearchDisplayController!
      
      	// 实例化搜索条
      	let searchBar:UISearchBar = UISearchBar(frame: CGRectMake(0, 0, self.view.frame.size.width, 44))
      
      	// 实例化搜索控制器对象
      	mySearchDisplayController = UISearchDisplayController(searchBar: searchBar, 
      	                                             contentsController: self)
      
      	// 设置搜索控制器的代理
      	mySearchDisplayController.delegate = self
      
      	// 为搜索控制器自带 tableView 指定代理
      	mySearchDisplayController.searchResultsDelegate = self
      	mySearchDisplayController.searchResultsDataSource = self
      
      	// 将搜索条设置为 tableView 的表头
      	myTableView.tableHeaderView = searchBar
      
    • UISearchDisplayDelegate 协议方法

      	// 更新搜索结果
      	/*
      		只要搜索框的文字发生了改变,这个方法就会触发。searchString 为搜索框内输入的内容
      	*/
      	func searchDisplayController(controller: UISearchDisplayController, shouldReloadTableForSearchString searchString: String?) -> Bool {
      	
      		// 清空上一次搜索的内容
      		mySearchResultArray.removeAll()
      
      		// 将搜索的结果存放到数组中
      		for subArray in myDataArray {
      			for str in subArray {
          
      				let range:NSRange = (str as NSString).rangeOfString(searchString!)
          
      				if range.length != 0 {
      					mySearchResultArray.append(str)
      				}
      			}
      		}
      
      		return true
      	}
      
    • UITableView 协议方法

      	// 设置分段头标题
      	func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
          
          	if tableView == myTableView {
          		return "(Character(UnicodeScalar(65 + section)))"
          	}
          	return "搜索结果"
      	}
      
      	// 设置分段数
      	func numberOfSectionsInTableView(tableView: UITableView) -> Int {
          
          	if tableView == myTableView {
      			return myDataArray.count
          	}
          	return 1
      	}
      
      	// 设置行数
      	func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
          
      		if tableView == myTableView {
              
      			return myDataArray[section].count
      		}
      		return mySearchResultArray.count
      	}
      
      	// 设置每段显示的内容
      	func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
          
          	var cell = tableView.dequeueReusableCellWithIdentifier("testIdentifier")
          
          	if cell == nil {
          		cell = UITableViewCell(style: .Default, reuseIdentifier: "testIdentifier")
          	}
          
          	if tableView == myTableView {
      			cell!.textLabel?.text = myDataArray[indexPath.section][indexPath.row]
          	}
          	else {
          		cell!.textLabel?.text = mySearchResultArray[indexPath.row]
          	}
          
          	return cell!
      	}
      

1.2 在 iOS 8.0 及以上版本中

  • Objective-C

    • 遵守协议 UISearchResultsUpdating

    • 搜索结果数组初始化

      	// 声明搜索结果存放数组
      	@property(nonatomic, retain)NSMutableArray *mySearchResultArray;
      
      	// 初始化搜索结果存放数组
      	mySearchResultArray = [[NSMutableArray alloc] init];
      
    • searchController 初始化

      	// 声明搜索控制器,自带一个表格视图控制器,用来展示搜索结果,必须设置为全局变量
      	@property(nonatomic, retain)UISearchController *mySearchController;
      
      	// 实例化搜索控制器
      	mySearchController = [[UISearchController alloc] initWithSearchResultsController:nil];
      
      	// 设置搜索代理
      	mySearchController.searchResultsUpdater = self;
      
      	// 设置搜索条大小
      	[mySearchController.searchBar sizeToFit];
      
      	// 设置搜索期间背景视图是否取消操作,default is YES
      	mySearchController.dimsBackgroundDuringPresentation = NO;
      
      	// 设置搜索期间是否隐藏导航条,default is YES
      	mySearchController.hidesNavigationBarDuringPresentation = NO;
      
      	// 将 searchBar 添加到表格的开头
      	myTableView.tableHeaderView = mySearchController.searchBar;
      
    • UISearchResultsUpdating 协议方法

      	// 更新搜索结果
      	/*
      		只要搜索框的文字发生了改变,这个方法就会触发。searchController.searchBar.text 为搜索框内输入的内容
      	*/
      	- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
      
      		// 清除上一次的搜索结果
          	[mySearchResultArray removeAllObjects];
      
          	// 将搜索的结果存放到数组中
          	for (NSArray *subArray in myDataArray) {
      			for (NSString *str in subArray) {
                  
      				NSRange range = [str rangeOfString:searchController.searchBar.text];
                  
      				if (range.length) {
      					[mySearchResultArray addObject:str];
      				}
      			}
          	}
          
          	// 重新加载表格视图,不加载的话将不会显示搜索结果
          	[myTableView reloadData];
      	}
      
    • UITableView 协议方法

      	// 设置分段头标题
      	- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
          
      		if (mySearchController.active) {
              
      			return @"搜索结果";
      		}
      		return [NSString stringWithFormat:@"%c", (char)('A' + section)];
      	}
      
      	// 设置分段数
      	- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
      	
      		if (mySearchController.active) {
              
      			return 1;
      		}
      		return myDataArray.count;
      	}
      
      	// 设置行数
      	- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
          
      		if (mySearchController.active) {
              
      			return mySearchResultArray.count;
      		}
      		return [[myDataArray objectAtIndex:section] count];
      	}
      
      	// 设置每段显示的内容
      	- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
          
      		UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"testIdentifier"];
          
      		if (!cell) {
      			cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"testIdentifier"];
      		}
          
      		if (mySearchController.active) {
      			cell.textLabel.text = [mySearchResultArray objectAtIndex:indexPath.row];
      		}
      		else {
      			cell.textLabel.text = [[myDataArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
      		}
          
      		return cell;
      	}
      
  • Swift

    • 遵守协议 UISearchResultsUpdating

    • 搜索结果数组初始化

      	// 初始化搜索结果存放数组
      	var searchResultArray:[String] = Array()
      
    • searchController 初始化

      	// 声明搜索控制器,自带一个表格视图控制器,用来展示搜索结果,必须设置为全局变量
      	var mySearchController:UISearchController!
      
      	// 实例化搜索控制器
      	mySearchController = UISearchController(searchResultsController: nil)
      
      	// 设置搜索代理
      	mySearchController.searchResultsUpdater = self
      
      	// 设置搜索条大小
      	mySearchController.searchBar.sizeToFit()
      
      	// 设置搜索期间背景视图是否取消操作,default is YES
      	mySearchController.dimsBackgroundDuringPresentation = false
      
      	// 设置搜索期间是否隐藏导航条,default is YES
      	mySearchController.hidesNavigationBarDuringPresentation = false
      
      	// 将 searchBar 添加到表格的开头
      	myTableView.tableHeaderView = mySearchController.searchBar
      
    • UISearchResultsUpdating 协议方法

      	// 更新搜索结果
      	/*
      		只要搜索框的文字发生了改变,这个方法就会触发。searchController.searchBar.text 为搜索框内输入的内容
      	*/
      	func updateSearchResultsForSearchController(searchController: UISearchController) {
      	
      		// 清除上一次的搜索结果
          	searchResultArray.removeAll()
      
      		// 将搜索的结果存放到数组中                
          	for subArray in myDataArray {
      			for str in subArray {
                  
      				let range:NSRange = (str as NSString).rangeOfString(searchController.searchBar.text!)
      
      				if range.length != 0 {
      					searchResultArray.append(str)
      				}
      			}
          	}
          	
          	// 重新加载表格视图,不加载的话将不会显示搜索结果
          	myTableView.reloadData()
      	}
      
    • UITableView 协议方法

      	// 设置分段头标题
      	func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
          
      		if mySearchController.active {
      			return "搜索结果"
      		}
      		return "(Character(UnicodeScalar(65 + section)))"
      	}
      
      	// 设置分段数
      	func numberOfSectionsInTableView(tableView: UITableView) -> Int {
          
      		if mySearchController.active {
              
      			return 1
      		}
      		return myDataArray.count
      	}
      
      	// 设置行数
      	func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
          
      		if mySearchController.active {
              
      			return searchResultArray.count
      		}
      		return myDataArray[section].count
      	}
      
      	// 设置每段显示的内容
      	func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {       		
          
      		var cell = tableView.dequeueReusableCellWithIdentifier("testIdentifier")
          
      		if cell == nil {
      			cell = UITableViewCell(style: .Default, reuseIdentifier: "testIdentifier")
      		}
          
      		if mySearchController.active {
      			cell!.textLabel?.text = searchResultArray[indexPath.row]
      		}
      		else {
      			cell!.textLabel?.text = myDataArray[indexPath.section][indexPath.row]
      		}
          
      		return cell!
      	}
      
原文地址:https://www.cnblogs.com/QianChia/p/5758927.html