swift UI专项训练37 实时显示搜索结果的搜索框SearchBar

简介:     今天我们来讲点高级点的知识,在搜索框中输入关键字,下方的tableView自动匹配包含关键字的结果。

    今天我们来讲点高级点的知识,在搜索框中输入关键字,下方的tableView自动匹配包含关键字的结果。用我最近在做的一款美食类APP为例。

在storyboard中拖入一张表,然后与Vc中的代码关联起来:

@IBOutlet weak var tableView: UITableView!

获取我们所需要的菜品信息:

var caipins = CaipinArray().caipinArray
    var searchResults = [caipin]()

caipins是所有的菜品,searchResults是我们通过搜索的菜品信息,它们都是caipin类,caipin类是我们之前定义好的,格式如下:

import UIKit

class caipin: NSObject {
    var name:String = ""
    var rest:String = ""
    var price:Float = 0
    var score:Float = 0
    var image:String = ""
    var collected:Bool = false
    var taste:String = ""
    var nutrition:String = ""
    init(name:String,rest:String,price:Float,score:Float,image:String,collected:Bool,taste:String,nutrition:String){
    self.name = name
    self.rest = rest
    self.price = price
    self.score = score
    self.image = image
    self.collected = collected
    self.taste = taste
    self.nutrition = nutrition
    }
}

CaipinArray是一个赋值过的菜品类,就不演示代码了,然后我们让vc继承tableview的datasource和delegate,实现这两个类的基本方法,本话重点不在这里就不演示了。

然后我们定义一个UISearchController的类:

var searchController:UISearchController!

在viewDidLoad方法中加入以下代码:

self.tableView.tableFooterView = UIView(frame: CGRectZero)
       searchController = UISearchController(searchResultsController: nil)
        searchController.searchBar.sizeToFit()
        self.view.addSubview(searchController.searchBar)
        tableView.tableHeaderView = searchController.searchBar
        definesPresentationContext = true
为了清楚我提前在tableview中加入了一些数据。现在运行看看,是不是tableview的顶端出现了搜索框:

点击搜索框效果如下:


现在新建一个方法:

func filterContentForSearchText(searchText: String) {
        
        searchResults = caipins.filter({ ( caipin: caipin) -> Bool in
            
            let nameMatch = caipin.name.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
            let locationMatch = caipin.rest.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
            
            return nameMatch != nil || locationMatch != nil
            
        })
       IOS中给我们封装好了一个filter(过滤),我们可以在已经存在的数组中直接用,只需要在闭包中提供这个过滤的规则,以上的代码我们定义了两个规则,一个是匹配菜品名字或者匹配菜品所属的餐馆名称,返回的结果是一个布尔类型,通知程序有没有匹配的项。现在我们已经对输入的搜索关键字进行了判断,那么我们如何根据判断结果来更新列表中的值呢?

首先要做的一点就是集成一个UISearchResultsUpdating的接口:

class SecondViewController: UIViewController,UITableViewDataSource,UISearchResultsUpdating

这个接口定义了一个叫做

updateSearchResultsForSearchController 的方法,当我们对搜索框有任何操作的时候这个方法就会被调用,我们可以让我们呢的search controller做我们的返回。现在来实现这个方法:

func updateSearchResultsForSearchController(searchController: UISearchController) {
        let searchText = searchController.searchBar.text
        
        filterContentForSearchText(searchText)
        
        tableView.reloadData()
    }

在这个方法中,我们得到用户的输入,传给filterContentForSearchText方法,因为要在一张表中显示输出结果,所以最后要把表reload一下。接下来需要更新一下我们之前定义的方法。首先是tableView(_:numberOfRowsInSecton:)这个方法。search是否被用户激活是有一个标识符的,我们可以直接使用,当被激活的时候显示搜索集中的菜品,不然就不显示:

 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
            return searchResults.count
        
    }

列表只显示搜索到的菜品信息。接下来修改t ableView(_:cellForRowAtIndexPath:)  方法
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let identiString = "sCell" //代码复用
        let cell = tableView.dequeueReusableCellWithIdentifier(identiString , forIndexPath: indexPath) as searchTableViewCell
       
        var caipin =
        caipins[indexPath.row]
        if searchResults.count != 0
        {
            println(searchResults.count)
            caipin = searchResults[indexPath.row]
        }
        
        cell.nameLabel.text = caipin.name
        cell.scoreLabel.text = "评分:" + "\(caipin.score)"
        cell.restLabel.text = "餐馆:" + caipin.rest
        cell.priceLabel.text = "价格:" + "\(caipin.price)"
        cell.caipinImageView.image = UIImage(named: caipin.image)
        
        if caipin.collected == true {
            cell.shoucangImageView.image = UIImage(named: "heart_fill_28")
        }
        
        return cell
    }
因为如果没有搜索到的话我们的结果集是空的,如果直接返回给caipin的话会显示空值。这是因为swift中向一个空数组中插值只能用append或者+-,直接使用空数组中的元素会报 Cannot index empty buffer 这个错误,所以思考再三我增加了一个判断语句,如果搜索结果集中没有元素,那么返回所有元素的集合,因为tableview的行数被我们定义成搜索结果集的元素个数,所以此时表中依旧不显示元素。当搜索结果集中有值的时候,我们可以放心的使用它当中的元素和属性。

最后一步,我们需要给viewDidLoad方法加入以下代码:

searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false

第一行指定当前类作为更新数据的结果集,而第二行是因为我们在当前的view中返回结果。

另外更改一下搜索框中的水印文字:

searchController.searchBar.placeholder = "请输入菜品或餐馆"

快来运行看看效果吧。


回到搜索界面发现列表中已经没有东西了,在搜索框中输入一个“芳”:


可以看到菜品中和餐馆中包含“芳”字的结果都显示了出来!这就是swift的强大之处,只是用了很简单的代码就实现了这么好用的功能,快来试试吧。





目录
相关文章
|
机器学习/深度学习 数据可视化 算法
基于深度学习的瓶子检测软件(UI界面+YOLOv5+训练数据集)
基于深度学习的瓶子检测软件(UI界面+YOLOv5+训练数据集)
260 0
|
7月前
SAP 电商云 Spartacus UI 产品搜索结果的设计明细
SAP 电商云 Spartacus UI 产品搜索结果的设计明细
39 0
|
7月前
|
Web App开发 前端开发 JavaScript
SAP UI5 应用开发教程之七十八 - 如何通过 url 保持 SAP UI5 搜索的状态,让其支持书签功能试读版
SAP UI5 应用开发教程之七十八 - 如何通过 url 保持 SAP UI5 搜索的状态,让其支持书签功能试读版
38 0
|
8月前
|
存储 数据管理 数据库
CoreData 在 swift UI 中的使用
当谈到在 Swift UI 中进行本地数据持久化,Core Data 是一个强大且常用的解决方案。Core Data 是苹果提供的一种数据存储和管理框架,用于在应用程序中创建、读取、更新和删除数据。它提供了一个对象图管理器,可以将数据映射到对象,并提供了一种简化数据操作的方式。在本文中,我们将深入介绍 Core Data 在 Swift UI 中的使用。
CoreData 在 swift UI 中的使用
|
8月前
|
前端开发
前端项目实战捌拾柒react-admin+material ui-踩坑-List的用法之aside组件FilterLiveSearch搜索按钮
前端项目实战捌拾柒react-admin+material ui-踩坑-List的用法之aside组件FilterLiveSearch搜索按钮
48 0
|
机器学习/深度学习 数据可视化 算法
水果新鲜程度检测系统(UI界面+YOLOv5+训练数据集)
水果新鲜程度检测系统(UI界面+YOLOv5+训练数据集)
466 0
|
机器学习/深度学习 传感器 监控
基于YOLOv5的停车位检测系统(清新UI+深度学习+训练数据集)
基于YOLOv5的停车位检测系统(清新UI+深度学习+训练数据集)
465 0
|
机器学习/深度学习 人工智能 监控
基于深度学习的人群密度检测系统(UI界面+YOLOv5+训练数据集)
基于深度学习的人群密度检测系统(UI界面+YOLOv5+训练数据集)
515 0
|
机器学习/深度学习 监控 算法
智能生活垃圾检测与分类系统(UI界面+YOLOv5+训练数据集)
智能生活垃圾检测与分类系统(UI界面+YOLOv5+训练数据集)
671 0
|
机器学习/深度学习 人工智能 算法
基于深度学习的农作物叶片病害检测系统(UI界面+YOLOv5+训练数据集)
基于深度学习的农作物叶片病害检测系统(UI界面+YOLOv5+训练数据集)
424 1

相关课程

更多