如何使用Swift添加Table View搜索框

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用Swift添加Table View搜索框相关的知识,希望对你有一定的参考价值。

Xcode6新建一个项目,采用swift创建代码:

创建一个ViewController继承UITableViewController

涉及了模型,控制器

模型:ZLPlace.swift

class ZLPlace: NSObject  
var place = ""  
var visited = false  
 

tableViewController 控制器

import UIKit  
 
class ViewController: UITableViewController  
      
    // 静态数据数组,存放模型  
    var arrs = [ZLPlace]()  
      
    override func viewDidLoad()  
        super.viewDidLoad()  
          
        let place2 = ZLPlace()  
        place2.place = "zhang2"  
        arrs.append(place2)  
          
        let place3 = ZLPlace()  
        place3.place = "zhang3"  
        arrs.append(place3)  
          
        let place4 = ZLPlace()  
        place4.place = "zhang1"  
        arrs.append(place4)  
          
        self.tableView.reloadData()  
     
      
    // 数据源方法, 返回多少组  
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int  
        return 1;  
     
      
    // 每组有多少行  
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int  
        return arrs.count;  
     
      
    // 每行展示什么内容  
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell  
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell  
          
        let place = arrs[indexPath.row]  
          
        cell.textLabel.text = place.place  
          
        return cell;  
          
     
      
    // 点击每个cell触发什么事件  
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)  
          
        let place = arrs[indexPath.row]  
        place.visited = !place.visited;  
          
        let cell = tableView.cellForRowAtIndexPath(indexPath)  
        cell?.backgroundColor = UIColor.clearColor()  
        if(place.visited)  
            cell?.accessoryType = UITableViewCellAccessoryType.Checkmark  
        else  
            cell?.accessoryType = UITableViewCellAccessoryType.None  
         
     
      
    // 点击编辑按钮  
    @IBAction func editing(sender: AnyObject)  
        self.tableView.setEditing(true, animated: true)  
     
      
    // 删除每个cell  
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)  
        if editingStyle == UITableViewCellEditingStyle.Delete  
            arrs.removeAtIndex(indexPath.row)  
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Top)  
         
     
      
 

效果如图:

参考技术A 在Xcode中,选择 File\New\Project… 创建一个新项目。选择 Single View Application 点 Next 。将项目命名为 CandySearch 确保 Language 设置为 Swift 并且 Devices 设置为 iPhone 。点击完成,选择你想储存的位置,然后点击 Create 。
首先将默认的文件清理掉,这样你就可以真正的从头开始。在 Project Navigator 中,选择 ViewController.swift ,右键点击,选择删除,然后选择 Move to Trash 。然后打开 Main.storyboard ,选择唯一的一个view controller然后删掉他。现在你有一个空的storyboard,可以在你的应用中添加主屏幕了。
从 Object Browser (边框控制条的右下部分)拖出 Navigation Controller 以将ios内置的导航逻辑添加到项目中。这样可以在storyboard中创建两个view controllers – navigation controller和table view controller,这些将作为应用的初始视图。
当用户选择列表中的某一项时,你需要一个视图控件来显示详细的内容。从Table View Controller中拖拽,一直到那个新的view controller释放,并且在弹出的菜单中选择 show 来作为manual segue的选项。
设置糖果类
下一步你将创建一个用来显示糖果的数据结构,保存像策略和名称类的信息。在 CandySearch 文件夹上点击右键,然后选择 New File… 。选择 iOS \ Source \ Swift File 然后点击下一步。将此文件命名为 Candy.swift 。打开文件,然后添加如下内容:
struct Candy

let category : String

let name : String



这个结构有两个属性:糖果的策略和名称。当你的用户在应用中搜索糖果时,会引用名称属性对用户搜索的字符串进行比较。你文章稍后将会发现策略字符串在你实现分类条时有多么重要。
你不需要在这里添加自己的初始化,你能得到一个自动生成的机制。默认的,初始化参数将对属性进行配置。在下一个部分中你将看到如何创建 candy 实例。
现在你已经准备好设置 UITableView 以使你的 UISearchBar 能够过滤信息!
连接Table View
下一步你将设置 UITableView 让他和 UISearchBar 一起工作。右键点击 CandySearch 文件夹并且选择 New File… 。选择 iOS \ Source \ Cocoa Touch Class 点击下一步。类命名为 CandyTableViewController ,父类设置为 UITableViewController 并且设置语言为 Swift 。
开始的时候我们需要添加一个数组。打开 CandyTableViewController.swift 并且增加如下代码:
var candies = [Candy]()

candies 数组将会管理所有不同的 Candy 对象,以便用户搜索。说到这里,是时候创建你的糖果了!在这篇引导中,你只需要创建一个数量区间,用来说明搜索条如何工作;在制作应用的过程中,你会发现你有成千上万的条目需要检索。但是不论你的应用程序有多少条目,搜索的方法都是相同的。具有可伸缩性是最好的!为了能够布置好你的 candies 数组,重写 viewDidLoad 如下:
override func viewDidLoad()

super.viewDidLoad()

// 向candyArray中添加简单的数据

self.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")]

// 刷新table

self.tableView.reloadData()



这段代码并没做太多的设置,但他做了一些重要设置。首先它填充了9个有不同名称和类别的糖果。你将在填充数组后使用它。然后你让tableView重新载入数据。你必须这么做,以确保所有的糖果信息都被显示。
下一步,你将添加控制表视图本身的功能。实现 tableView(_:numberOfRowsInSection:) 如下:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int

return self.candies.count



这里简单的告诉 tableView ,应该包含许多行,而这个数量是你在 candies 数组中确定的。
现在 tableView 知道了需要准备多少行,你需要告诉他每行需要放什么内容。实现tableView(_:cellForRowAtIndexPath:):
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell

// 在tableview中查询一个条目,如果没有创建一个。

let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell

// 从我们的糖果数组中获得相应的内容

let candy = self.candies[indexPath.row]

// 设置条目

cell.textLabel!.text = candy.name

cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator

return cell



这个方法主要分三个部分。首先,你使用 indexPath 选出条目。然后检索 candies数组,根据 indexPath 决定哪个 Candy 需要提取,然后使用 Candy 对象实现 UITableViewCell 实例。

注意 :如果你在之前已经使用过Table Views,你也许会怀疑为什么没有实现 heightForRowAtIndexPath 。在iOS8中,这个方法已经不再支持;操作系统在运行时自动决定元素的大小。这岂不是更好吗?:]当然,如果你打算让你的应用支持早期iOS版本,你还是需要实现这个方法。
现在你做的差不多了!还需要一个步骤你就可以看到糖果列表了。你需要实现故事板中的所有代码。首先,打开 Main.storyboard 并且选择 Root View Controller 。在Identity Inspector 中(右边栏中顶部第三个选项卡),设置 Class 为 CandyTableViewController 。这将会告诉操作系统当你的控件呈现在屏幕时加载你指定的关联类。好了,现在,双击 CandySearch 根视图控件的标题,然后修改他,这可以给你的用户一些关于他们能在软件中做什么的提示。
最后,你需要让你的操作系统知道你的代码是用于做什么的。你需要注意当你修改故事板的之前,一个默认的元素已经存在于你的table view中。选择这个元素(通常被命名为”Cell”)并且打开Attributes Inspector(位置在Identity Inspector的右边)。修改 Identifier 为 Cell 。这将重新匹配你早期代码中元素的标示符。
保存你的修改并运行。现在你有了一个正在工作的列表视图!许多的糖果。。。呈现这些只花了极短的时间!接下来我们需要一个UISearchBar!

设置UISearchBar
如果你查看过 UISearchBar 的文档,你将发现作者非常的懒惰。作者没有提供任何具体的搜索接口!这个类只是提供了一些用户所期望的接口。他更像是一个中级的管理类;擅长将任务委托给他人。
UISearchBar 这个类使用一个代理接口进行通讯,使你的应用知道用户做了些什么。所有的字符串匹配和其他的操作都需要你自己编写完成。尽管这个看起来有点可怕(有点不公平!),但写自定义的搜索方法给了你的应用完善的控制返回结果的体验。你的用户将会欣赏你提供的搜索结果 – 并且也会更快速。
打开 Main.storyboard 并且拖放一个 Search Bar and Search Display Controller 对象到视图控制器。注意 – 这里和 Search Bar 对象有一些不同,他也是有效的。调整搜索条的位置。
不能明白搜索显示控制器的意思?根据苹果自己的文档,一个搜索显示控制器是“管理搜索条的显示,具体来说是一个显示另一个视图控制器搜索结果的table view”。
这意味着区别于你刚才设置的, 搜索控件将有他自己的table view用来显示结果。简单的来说,先在显示控件中增加上层操控,然后把一个搜索中生成的过滤数据放入一个单独的视图控制器,这一点你丝毫不用自己操心。:]
UISearchBar中Attributes inspector的选项
在故事板中,花些时间重新查看搜索条对象的可用属性。你也许不会全部使用到,但使用一个新的UIKit组件之前了解 Attributes Inspector 是值得的。
Text :这将改变呈现在搜索条上的字符串。如果你的应用需要使用默认值,你是不需要修改这一属性的。
Placeholder : 这正是你所期望的 – 他允许你放置一个浅灰色的文本以高速你的用户搜索条可以做什么。在这个糖果应用中,我们使用 “搜索你的糖果”。
Prompt : 这个文本将会直接显示在搜索条的上方。这有利于对复杂的搜索机制进行说明。(但在这个应用中,Placeholder应该更显而易懂!)
Search Style, Bar Style, Translucent, Tint, Background and Scope Bar Images : 这些选项允许你自定义搜索条的呈现。这些选项是为了是你的UISearchBar和UINavigationBar看起来更和谐。
Search Text and Background Positions : 这些选项允许你添加文本与搜索框的偏移量。
Show Search Results Button : 在搜索条的右边提供一个按钮为了执行像显示最近搜索或者显示最后搜索的方法。搜索栏与这个按钮的交互是通过代理方法来实现的。
Show Bookmarks Button : 在搜索栏右边显示标准的蓝色椭圆形书签。这将有一个用户希望保存的搜索书签。像结果按钮一样,也是通过代理来实现的。
Show Cancel Button : 这个按钮允许用户关闭搜索栏单独生成的视图控制器。如果这个选项没有选中,搜索栏会在隐藏取消按钮并在搜索模式中自动显示。
Shows Scope Bar & Scope Titles : 分类条允许用户用特定的策略进行搜索。比如在音乐应用中,这个控件条也许会显示艺术家,专辑或者流派。对于当前项目,保持这个选项没有被选中;你将实现自己的分类标签。
Capitalize, Correction, Keyboard, etc. : 这些选项都借用了UITextField的内容,可以让你改变搜索条的行为。例如,如果用户想搜索专业名词或者是人名,这是就可以关闭自动修正,以避免不必要的麻烦。在本教程中,糖果的名字都是普通的名称,所以保持默认选项就可以了。

注意 :了解一些有用的选项可以为你的开发节省许多时间。所以对于一个iOS未来的开发者,是要经常花时间搜索可用的资源。
UISearchBarDelegate和过滤器
设置了故事板以后,你需要写一些代码来让搜索条工作。设置 CandyTableViewController 类响应搜索条,这需要实现一些接口。打开 CandyTableViewController.swift 并且将类的声明替换为下列代码:
class CandyTableViewController : UITableViewController, UISearchBarDelegate, UISearchDisplayDelegate

UISearchBarDelegate 定义了搜索的行为和响应方式,然后 UISearchDisplayDelegate 定义了搜索条的外观。
下一步,在类中添加如下属性:
var filteredCandies = [Candy]()

这个数组将保存过滤后的数据。
下一步,添加如下辅助方法到类里面:
func filterContentForSearchText(searchText: String)

// 使用过滤方法过滤数组

self.filteredCandies = self.candies.filter(( candy: Candy) -> Bool in

let categoryMatch = (scope == "All") || (candy.category == scope)

let stringMatch = candy.name.rangeOfString(searchText)

return categoryMatch && (stringMatch != nil)

)



这个方法将使用 searchText (也就是你的搜索字符串) 过滤 candies ,然后将结果放入 filteredCandies 。Swift的数组有一个叫做filter()的方法,他使用了一个闭合表达式作为他唯一的参数。
如果你有一些Objective-C的经验,仔细看一下闭合表达式在Swift中的表现形式。闭包是一个自包含的功能块。他们被称作闭包,是因为他们可以使用一段上下文捕获或储存任意变量或常量的引用,这被称为关闭。下面是一个闭合表达式的语法:
(parameters) -> (return type) in expression statements

在这个示例中,过滤方法使用闭合表达式来区分数组中的每一个元素。闭包表达式的参数用于对个别的元素进行排序。闭包表达式返回一个bool值,如果元素存在于过滤的数组中则返回true,如果返回false则说明没有包含在数组内。如果你仔细查看文档中的方法,你会注意到他使用了一个像 的类型。这是一个通用类型,这以为这他可以是任何类型。直到你使用闭包表达式定义自己的过滤规则,这个过滤方法可以使用在任何类型的过滤上。闭包表达式的参数也是一个 T 类型,其中的元素就是等待被过滤的。在你的代码中我们使用了 candy : Candy ,然后你了解了这个数组是被 Candy装满的:
rangeOfString() 用于检查是否字符串包含索要查找的字符串。如果是,则返回true,表明当前的糖果包含在过滤的数组中;如果返回false则不包含。
下一步,在类中添加如下代码:
func searchDisplayController(controller: UISearchDisplayController!, shouldReloadTableForSearchString searchString: String!) -> Bool

self.filterContentForSearchText(searchString)

return true



func searchDisplayController(controller: UISearchDisplayController!, shouldReloadTableForSearchScope searchOption: Int) -> Bool

self.filterContentForSearchText(self.searchDisplayController!.searchBar.text)

return true

iView中表格(Table)自定义表头添加模糊搜索框

参考技术A data()中表头columns部分

然后就是监听msgKeyword这个变量,执行search()方法

以上是关于如何使用Swift添加Table View搜索框的主要内容,如果未能解决你的问题,请参考以下文章

为 UIViewController 设置 ViewController,使用 Table View,连接到 Swift 中的 Parse

如何在Swift的Table View中进行分页?

ios 官网文档翻译—Create a Table View(swift)

text Swift中Table View的示例代码

如何使用 Swift 以编程方式添加约束

如何在 Swift 中的 View 中控制 TableView