如果你的应用程序里显示了大量的数据,滚动的查看大规模的列表会很慢,也会给人一种烦躁的感觉。在这种情况下,查询UISearchController, UISearchBar是极其重要的,可以让用户搜索特点的项目。非常幸运的是,UIKit包含了UISearchBar, 并且完美的集成了UITableView. 在这个UISearchController的教程中,你将要构建一个可搜索的糖果App, e而这个APP是基于标准的视图表。你将添加一个searchBar, 包括动态过滤,并添加一个可选的搜索范围,同时利用UISearchController。 最后你就会知道,如何让你的应用程序更加的满足用户需求。

准备好了搜索一些糖果的结果了么??

准备开始咯!

首先下载“最开始的项目here”,然后打开这个程序。 这个App已经被我设置了一个导航控制器和特定的风格。运行你的程序,你会看到一个空的列表:

返回到Xcode中,文件Candy.Swift包含了一个类来存储所有的信息关于你将要显示的糖果。这个类有两个属性,类别和糖果名字。

当用户在你的app中查找糖果的时候,你要把糖果的名字属性对应到用户搜索的字符串中。

填充表视图

打开MasterViewController.swift. candies属性将是你管理所有不同糖果的地方,说到这里,是时候创建一些糖果啦!

在这个教程里,你需要创建一些值来说明搜索栏是如何工作的。在app中,你可能有成千上万的这些可搜索的对象。但是应用程序是否有成千上万的对象搜索呢?其实方法都是相同的,可伸缩的是最好的。

为了填充你的candies数组,添加下面的代码到viewDidLoad(), 之后调用super.viewDidLoad():

candies = [
Candy(category:"Chocolate", name:"Chocolate Bar"),
Candy(category:"Chocolate", name:"Chocolate Chip"),
Candy(category:"Chocolate", name:"Dark Chocolate"),
Candy(category:"Hard", name:"Lollipop"),
Candy(category:"Hard", name:"Candy Cane"),
Candy(category:"Hard", name:"Jaw Breaker"),
Candy(category:"Other", name:"Caramel"),
Candy(category:"Other", name:"Sour Chew"),
Candy(category:"Other", name:"Gummi Bear")
]

运行你的项目,由于表格视图的代理和数据源方法已经实现了,你会发现你已经有了一个工作视图表啦:

选择表格里的任一一行,会对应的显示出来一个细节视图:

这么多的糖果,如此短的时间就找到你想要的那一款,那么 你需要一个UISearchBar.

UISearchController的简介

如果你看一下UISearchBar的文档,你会发现开发者很懒。它不做任何的搜索工作。类只是简单的提供了一个标准的接口,也就是用户从iOSapp里所期望的那样。

UISearchController和代理协议一起让其他应用程序知道用户做了什么。你必须写出所有的字符串来匹配给自己。

尽管这样讲起来可能有点吓人,但是编写自定义的搜索功能会严格控制在你的app中。如果你使用过ios搜索视图表,你应该会熟悉UISearchDisplayController. 自从IOS 8以来,这类UISearchController已经废弃 不再使用了,这样简化了整个搜索过程,但是,在编写文本时,界面构建器不支持UISearchController, 所以你必须通过编程的方式来创建UI.

在MasterViewController.swift, 添加一个新的属性:

let searchController = UISearchController(searchResultsController: nil)

通过初始化UISearchController, 你告诉你想要的搜索控制器,你搜索的结果显示使用相同的视图。如果你指定一个不同的视图管理器,那么它将会用来显示结果。

接下来,你将要设置一些searchController的参数。还是在MasterViewController.swift里, 添加下面的代码到viewDidLoad():

  searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar

让我们来解析一下写的这四行代码:

1. searchResultsUpdater是一个在UISearchController的属性,遵守UISearchResultsUpdating的协议。这个协议允许你的类被通知当UISearchBar的文本变化的时候。你需要在短时间内遵守这个协议。

2. 默认情况下,UISearchController将暗色调的呈现你的视图。这是非常有用的,但是如果你用的是另一个视图控制器来做searchResultsController,在这种情况下,你将设置当前的视图来显示结果,所以你不需要暗色调的视图。

3.通过设置definesPresentationContext为true, 你确保了searchBar不会一直在屏幕上当用户导航到另外一个视图控制器上。

4. 最后,你添加了searchBar到你的表格视图中的tableHeaderView. 记住这个接口尚未与UISearchController兼容,所以这是你必须要做的。

UISearch结果的更新和过滤。

当你设置好了搜索控制器之后,你需要写一些代码来让它工作。 首先呢,添加一下的属性到MasterViewController的顶部:

var filteredCandies = [Candy]()

这个属性就是用户要用来搜索糖果的,接下来,添加以下的方法到MasterViewController类里:

func filterContentForSearchText(searchText: String, scope: String = "All") {
filteredCandies = candies.filter { candy in
return candy.name.lowercaseString.containsString(searchText.lowercaseString)
}
 
tableView.reloadData()
}

这个过滤糖果的数组的建立是基于searchText, 然后将结果放到filteredCandies的数组里。你现在不用担心范围参数,你将会用到它在本章的最后一部分。

为了允许MasterViewController来回应searchBar,它将不得不实现UISearchResultsUpdateing.  打开MasterViewController.swift , 添加下面的扩展类,在MasterViewController这个类之外:

extension MasterViewController: UISearchResultsUpdating {
func updateSearchResultsForSearchController(searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
}

这个updateSearchResultForSeachController(_:)的方法是唯一方法来遵守UISearchResultsUpdating的协议。

现在,当用户在搜索栏,添加或删除文本时,UISearchController会通知MasterViewController这个类。这个方法本身是一个help方法的调用。filter()需要一个闭包(candy: candy)->Bool. 然后循环遍历所有元素的数组,通过当前的每一个元素。

你可以使用它来确定是否一个糖果应该在搜索结果里展示给用户。为了确定这一点,你需要返回true, 如果当前的糖果包含在数组里。如果不是,那么返回false.

containString(_:)是用来检查所有糖果的名字包含searchText. 你可以用lowercaseString方法将两个字符串转换为小写的。

运行你的项目吧。你会发现现在已经有了一个SearchBar搜索栏在图表的顶部。

但是,如果你输入一些文字,你还是看不到任何的结果和变化。 这个是因为你还没有编写代码的原因。图表视图还不知道你用了过滤结果。

回到MasterViewController.swift,代替tableView(_:numberOfRowsInSection:):

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.active && searchController.searchBar.text != "" {
return filteredCandies.count
}
return candies.count
}

其实也没有太大的改动啦,你可以查看是否用户在查询,和使用过滤后的正常糖果作为表的数据源。

接下来,替代tableView(_:cellForRowAtIndexPath:):

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let candy: Candy
if searchController.active && searchController.searchBar.text != "" {
candy = filteredCandies[indexPath.row]
} else {
candy = candies[indexPath.row]
}
cell.textLabel?.text = candy.name
cell.detailTextLabel?.text = candy.category
return cell
}

这两个方法的active属性是指的searchController确定要显示的数组。当用户点击搜索框的搜索栏,active将自动的设置为true.

如果搜索控制器是active的,你可以看到用户是否输入在搜索框的内容。如果有,返回的数据是来源自filteredCandies数组。否则,数据来自项目的完整列表。

我们来回想一下,搜索结果显示和隐藏的控制器自动处理,所以,所有代码要做的就是提供正确的数据,根据控制器的状态来判断是否用户已经搜索到一些东西了。

运行你的项目,你已经得到了一个有功能的搜索栏啦。

UISearchController,SearchBar的教程-Swift的更多相关文章

  1. HealthKit教程 Swift版:锻炼信息

    原文:HealthKit Tutorial with Swift: Workouts 作者:Ernesto García 译者:Mr_cyz ) 欢迎回到我们的HealthKit系列教程! 在我们系列 ...

  2. HealthKit开发教程Swift版:起步

    原文:HealthKit Tutorial with Swift: Getting Started 作者:Ernesto García 译者:Mr_cyz ) HealthKit是iOS 8中的新的A ...

  3. Swift新手教程系列5-函数+selector在swift中的使用方法

    原创blog.转载请注明出处 近期在用swift写代码,尽管遇到一些问题,可是代码量确实减了不少. swfit新手教程系列会随着我使用swfit中的积累,不断地去修正更新 之前的教程 swift单例模 ...

  4. Swift - 开源框架总结

    苹果官方Swift文档<The Swift Programming Language> 苹果开发者Swift文档及介绍 网友整理的Swift中文文档< Apple Swift编程语言 ...

  5. 总结swift语言常见的20个问题和回答

    1.假设我是个刚入门的iOS开发人员,选swift学习呢,还是选objective-c学习,还是两个都学? 这个能够依据两种情况来决定:1.我想进入公司担任iOS开发的职位    2.我仅仅想做个独立 ...

  6. iOS UISearchBar UISearchController

    搜索栏的重要性我们就不说了,狼厂就是靠搜索起家的,现在越来越像一匹没有节操的狼,UC浏览器搜索栏现在默认自家的神马搜索,现在不管是社 交,O2O还是在线教育等都会有一个搜索栏的实现,不过彼此实现效果是 ...

  7. iOS Sprite Kit教程之滚动场景

    iOS Sprite Kit教程之滚动场景 滚动场景 在很多的游戏中,场景都不是静止的,而是滚动的,如在植物大战僵尸的游戏中,它的场景如图2.26所示. 图2.26  植物大战僵尸 在图2.26中,用 ...

  8. iOS Sprite Kit教程之场景的切换

    iOS Sprite Kit教程之场景的切换 Sprite Kit中切换场景 每一个场景都不是单独存在的.玩家可以从一个场景中切换到另外一个场景中.本小节,我们来讲解场景切换.在每一个游戏中都会使用到 ...

  9. iOS Sprite Kit教程之场景的设置

    iOS Sprite Kit教程之场景的设置 Sprite Kit中设置场景 在图2.8所示的效果中,可以看到新增的场景是没有任何内容的,本节将讲解对场景的三个设置,即颜色的设置.显示模式的设置以及测 ...

随机推荐

  1. 洛谷 P2038 无线网络发射器选址

    题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻 ...

  2. java中IO流之字节字符流的总结概述

    概念        这么庞大的体系里面,常用的就那么几个,我们把它们抽取出来,如下图: Java语言定义了许多类专门负责各种方式的输入或者输出,这些类都被放在java.io包中.其中, 所有输入流类都 ...

  3. window.addEventListener介绍说明

    原型 public override function addEventListener(type:String, listener:Function, useCapture:Boolean = fa ...

  4. word中在空白处加下划线不显示解决

    终极解决:Ctrl + Shift + Space Alt + 选择,竖向选择.和VS,其他一些编辑器一样

  5. cocos2dx 3.x c++代码打包给lua调用过程(mac)

    下载cocos2dx 框架,在应用程序->cocos->framework->cocos2d-x-3.x->tools->tolua目录下,一个ini文件对应一个py文件 ...

  6. C#_接口基础学习

    参考:https://www.cnblogs.com/hamburger/p/4681681.html

  7. [图文]RHEL 7/CentOS 7/Fedora28 联网初始化

    实验说明: 入门Linux,一般会遇到以下几个问题: 从哪里获取LInux镜像? 如何通过镜像文件安装Linux系统? 安装实体机还是虚拟机? 安装完系统如何配置网络? 虚拟机的网络配置与实体机有何不 ...

  8. python入门:输出1-10的所有数

    #!/usr/bin/env python # -*- coding:utf-8 -*- #输出1-10的所有数 """ 变量kaishi的赋值为数字1,while 真, ...

  9. ccf 201803-4 棋局评估(Python实现)

    一.原题 问题描述 试题编号: 201803-4 试题名称: 棋局评估 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 Alice和Bob正在玩井字棋游戏. 井字棋游戏的规则很 ...

  10. Python基础——赋值机制

    使用id()函数用于获取对象的内存地址. 使用is来判断是不是指向同一个内存. 把一个对象赋值给另一个对象,两个对象都指向同一个内存地址. test=1000 test1=test id(test) ...