如何在Swift 3

时间:2017-04-03 06:09:32

标签: arrays swift object search

我正在尝试搜索我从Firebase数据库中提取的一组对象。数据加载正常,但当我尝试搜索没有任何节目。我现在只学习iOS / Swift大约6周了。以下是我的代码。

点击进入搜索栏后,应用就崩溃了。 我设法让搜索代码停止崩溃,但我的搜索没有得到任何回报。这是因为我正在搜索Firebase数据库吗?我正在将firebase数据加载到一个数组中,因此它应该可以搜索到吗?

import UIKit
import Firebase

class ServicesTableViewController: UITableViewController, UISearchResultsUpdating {

    var services = [Service]()
    var filteredSearch = [Service]()

    var searchController: UISearchController!
    var resultsController = UITableViewController()


    override func viewDidLoad() {
        super.viewDidLoad()


        // Turn this back on to cache data
        FIRDatabase.database().persistenceEnabled = true

        fetchServices()

        self.resultsController.tableView.dataSource = self
        self.resultsController.tableView.delegate = self

        self.searchController = UISearchController(searchResultsController: self.resultsController)
        self.tableView.tableHeaderView = searchController.searchBar
        self.searchController.searchResultsUpdater = self

        searchController.dimsBackgroundDuringPresentation = false
        searchController.searchBar.placeholder = "Search services..."
        searchController.searchBar.tintColor = UIColor.white
        searchController.searchBar.barTintColor = UIColor(red: 164.0/255.0, green: 45.0/255.0, blue: 9.0/255.0, alpha: 1.0)

        navigationItem.backBarButtonItem = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
    }

    // MARK: - Search Controller

    func filterContent(for searchText: String) {
        filteredSearch = services.filter({ (service) -> Bool in
            if let name = service.name {
                let isMatch = name.localizedCaseInsensitiveContains(searchText)
                return isMatch
            }

            return false
        })
    }

    func updateSearchResults(for searchController: UISearchController) {
        if let searchText = searchController.searchBar.text {
            filterContent(for: searchText)
            tableView.reloadData()
        }
    }

    // MARK: Database connection and data fetch

    func fetchServices () {

        FIRDatabase.database().reference().child("services").observe(.childAdded, with: { (snapshot) in

            print(snapshot)

            if let dictionary = snapshot.value as? [String: AnyObject] {

                let service = Service()
                service.setValuesForKeys(dictionary)

                self.services.append(service)


                self.tableView.reloadData()



            }

        })


    }



    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {

        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if searchController.isActive {
            return filteredSearch.count
        } else {
            return services.count
        }
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellIdentifier = "Cell"
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! ServicesTableViewCell


        // Check to see if the user is searching or not
        let service = (searchController.isActive) ? filteredSearch[indexPath.row] : services[indexPath.row]

//        let service = services[indexPath.row]
        cell.programLabel.text = service.name
        cell.programLabel.font = UIFont(name: "Avenir-Medium", size: 18.0)
        cell.programLabel.textColor = UIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 1.0)
        cell.branchLabel.text = service.branch
        cell.branchLabel.font = UIFont(name: "Avenir-Medium", size: 14.0)
        cell.branchLabel.textColor = UIColor(red: 90.0/255.0, green: 86.0/255.0, blue: 92.0/255.0, alpha: 1.0)
        cell.servicesLabel.text = service.shortDesc
        cell.servicesLabel.font = UIFont(name: "Avenir-Light", size: 14.0)
        cell.servicesLabel.textColor = UIColor(red: 164.0/255.0, green: 45.0/255.0, blue: 9.0/255.0, alpha: 1.0)
        cell.thumbnailImageView.image = UIImage(named: service.imageName!)


        return cell
    }


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showServicesDetail" {
            if let indexPath = tableView.indexPathForSelectedRow {
                let destinationController = segue.destination as! ServicesDetailViewController
                destinationController.services = services[indexPath.row]
            }
        }
    }





}

这是我目前的故事板。只有两个视图和一个导航控制器, enter image description here

3 个答案:

答案 0 :(得分:0)

我以为你想按名字搜索:

filteredSearch = services.filter { (service: Service) -> Bool in

    if let name = service.name,
        let searchText = self.searchController.searchBar.text?.lowercased() {
        return name.lowercased().contains(searchText)
    } else {
        return false
    }
}

另外,请将filteredSearch更改为Service

的数组
var filteredSearch = [Service]()

答案 1 :(得分:0)

如果您的Service课程如下

class Service: NSObject {
    var serviceID: NSInteger!
    var serviceName: String!

}

您可以通过

检索包含serviceName的{​​{1}}过滤服务
self.searchController.searchBar.text

希望这有帮助。

答案 2 :(得分:0)

我有一个对象数组(codeDataObjectList)

    import Foundation

    class CodeDataObject:NSObject{

        private var collections:[String]?
        private var code: String?
        private var shortDescription: String?
        private var longDescription: String?
        private var sectionName: String?
        private var specialtyName: String?
        private var chapterName: String?
        private var isStarred: Bool?
        private var starredListIndex:Int?
        private var type: String?
        .
        .
        .

下面的代码可以搜索每个对象中的文本,您可以使用filteredTableData

更新表格数据
func  updateSearchResults(for searchController: UISearchController) {
        filteredTableData.removeAll(keepingCapacity: false)
        let searchPredicate = NSPredicate(format: "code CONTAINS[c] %@ OR longDescription CONTAINS[c] %@ OR shortDescription CONTAINS[c] %@", searchController.searchBar.text!, searchController.searchBar.text!, searchController.searchBar.text!)
        let array = (self.codeDataObjectList as NSArray).filtered(using: searchPredicate)
        filteredTableData = array as! [CodeDataObject]
        self.tableView.reloadData()
    }