使搜索功能快速响应 ui 搜索栏中键入的文本 [swift]

Posted

技术标签:

【中文标题】使搜索功能快速响应 ui 搜索栏中键入的文本 [swift]【英文标题】:make the search function respond quickly to the keyed in text in ui search bar [swift] 【发布时间】:2016-03-27 03:38:48 【问题描述】:

我一直在为我的 ios 应用程序开发搜索功能。目前我设法使它工作,但是只有当用户完成编写文本并单击搜索按钮时,搜索才会开始。即使键入第一个字母,如何通过查询开始快速响应?我目前正在使用带有 UIView 控制器的搜索栏,而不是 UITableViewController。

这是我的代码:

//
//  CoffeeListViewController.swift
//  CoffeeApp
//
//  Created by izzuddin on 14/03/2016.
//  Copyright © 2016 izzuddin. All rights reserved.
//

import UIKit
import CloudKit
import FBSDKCoreKit
import FBSDKLoginKit


class CoffeeListViewController: UIViewController 

    ////////////////////////////OUTLET

    @IBOutlet weak var tableview: UITableView!
    var coffees = [Coffee]()
    var filteredNames = [Coffee]()

    @IBOutlet weak var searchBar: UISearchBar!




    ////////////////////////////SPINNER

    var loadingView = UIView()
    var container = UIView()
    var activityIndicator = UIActivityIndicatorView()


    func showLoading() 

        let win:UIWindow = UIApplication.sharedApplication().delegate!.window!!
        self.loadingView = UIView(frame: win.frame)
        self.loadingView.tag = 1
        self.loadingView.backgroundColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 0)

        win.addSubview(self.loadingView)

        container = UIView(frame: CGRect(x: 0, y: 0, width: win.frame.width/3, height: win.frame.width/3))
        container.backgroundColor = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.6)
        container.layer.cornerRadius = 10.0
        container.layer.borderColor = UIColor.grayColor().CGColor
        container.layer.borderWidth = 0.5
        container.clipsToBounds = true
        container.center = self.loadingView.center


        activityIndicator.frame = CGRectMake(0, 0, win.frame.width/5, win.frame.width/5)
        activityIndicator.activityIndicatorViewStyle = .WhiteLarge
        activityIndicator.center = self.loadingView.center


        self.loadingView.addSubview(container)
        self.loadingView.addSubview(activityIndicator)

        activityIndicator.startAnimating()

    

    func hideLoading()
        UIView.animateWithDuration(0.0, delay: 1.0, options: .CurveEaseOut, animations: 
            self.container.alpha = 0.0
            self.loadingView.alpha = 0.0
            self.activityIndicator.stopAnimating()
            , completion:  finished in
                self.activityIndicator.removeFromSuperview()
                self.container.removeFromSuperview()
                self.loadingView.removeFromSuperview()
                let win:UIWindow = UIApplication.sharedApplication().delegate!.window!!
                let removeView  = win.viewWithTag(1)
                removeView?.removeFromSuperview()
        )
    





    ////////////////////////////LOAD DATA
    func call_data()
        self.showLoading()

        let container = CKContainer.defaultContainer()
        let publicData = container.publicCloudDatabase

        let query = CKQuery(recordType: "Coffee", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))
        publicData.performQuery(query, inZoneWithID: nil)  results, error in
            if error == nil  // There is no error
                for coffee in results! 
                    let newCoffee = Coffee()
                    newCoffee.name = coffee["Name"] as! String
                    newCoffee.cafe = coffee["Cafe"] as! String
                    newCoffee.rating = coffee["Rating"] as! Double
                    newCoffee.place = coffee["Place"] as? CLLocation

                    self.coffees.append(newCoffee)


                    dispatch_async(dispatch_get_main_queue(),  () -> Void in
                        self.tableview.reloadData()
                        self.hideLoading()

                    )
                
            
            else 
                print(error)
            
        
    




    //////////////////////////////////////////////////VIEW DID LOAD
    override func viewDidLoad() 
        super.viewDidLoad()
        call_data()

    





    //////////////////////////////////////////////////PREPARE SEGUE

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 


        if segue.identifier == "AddCoffeeVC" 
            let destVC: AddCoffeeViewController = segue.destinationViewController as! AddCoffeeViewController
            destVC.delegate = self
        

        if segue.identifier == "showCoffeeVC" 
            let destVC: ShowCoffeeViewController = segue.destinationViewController as! ShowCoffeeViewController

            if let selectedIndexPath = self.tableview.indexPathForSelectedRow 
                let coffee: Coffee = self.coffees[selectedIndexPath.row]
                destVC.coffeeDetail = coffee
            

        

    








    ////////////////////////////PASSING BACK DATA

    extension CoffeeListViewController : AddCoffeeDelegate

    func viewController(vc: AddCoffeeViewController, didAddCoffee coffee: Coffee!) 
        self.coffees.append(coffee)

        //create the cloudkit record here
        let container = CKContainer.defaultContainer()
        let publicData = container.publicCloudDatabase


        let record = CKRecord(recordType: "Coffee")
        record.setValue(coffee.name, forKey: "Name")
        record.setValue(coffee.cafe, forKey: "Cafe")
        record.setValue(coffee.rating, forKey: "Rating")
        record.setValue(coffee.place, forKey: "Place")
        publicData.saveRecord(record, completionHandler:  record, error in
            if error != nil 
                print(error)
            
        )


        self.dismissViewControllerAnimated(true, completion: nil)
        self.tableview.reloadData()
    






    ////////////////////////////////////////////////// ADPOPT TABLE VIEW

    extension CoffeeListViewController : UITableViewDelegate, UITableViewDataSource

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int

        return self.coffees.count

    


 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
        let cell = tableView.dequeueReusableCellWithIdentifier("CoffeeCell", forIndexPath: indexPath)

        let coffee = coffees[indexPath.row]
        cell.textLabel!.text = coffee.name
        cell.detailTextLabel!.text = "\(coffee.rating)"
        return cell
    







    ////////////////////////////////////////////////// SEARCH BAR


    extension CoffeeListViewController : UISearchBarDelegate 

    func searchBarShouldEndEditing( searchBar: UISearchBar)-> Bool
        searchBar.showsCancelButton = true
        return searchBar.showsCancelButton.boolValue
    

    func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool
        searchBar.showsCancelButton = true
        return searchBar.showsCancelButton.boolValue

    

    func searchBarCancelButtonClicked(searchBar: UISearchBar)
        searchBar.resignFirstResponder()
        searchBar.setShowsCancelButton(false, animated: false)
        call_data()


    

    func searchBarSearchButtonClicked(searchBar: UISearchBar)
        searchBar.resignFirstResponder()
    

    func searchBarTextDidEndEditing(searchBar: UISearchBar)

        var empty_array: [Coffee] = []

        for coffee in coffees
            if searchBar.text?.lowercaseString == coffee.name 
                empty_array.append(coffee)
            
        
        self.coffees = empty_array
        self.tableview.reloadData()

        NSLog("\(searchBar.text)")


    



【问题讨论】:

【参考方案1】:

您正在触发对searchBarTextDidEndEditing 的搜索。而是使用searchBar:textDidChange:,每次用户添加或删除字符时都会调用它。

(但是,如果您在这里使用 UISearchController 确实会更好。毕竟,这正是它的用途。)

【讨论】:

以上是关于使搜索功能快速响应 ui 搜索栏中键入的文本 [swift]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 bootstrap 3 导航栏中使 select2 v4 搜索框响应?

PyQt文本框搜索功能

当我在 google chrome /students/student_name 的搜索栏中键入此内容时,我想获取数组列表的此名称

当搜索栏成为第一响应者时更改表格 - swift

仅当搜索栏文本不为空时,如何运行过滤器功能?

以编程方式禁用移动 Chrome 43 的“触摸搜索”功能