Swift - Having problems with SearchBar in a custom TableViewController

时间:2017-08-04 12:15:35

标签: ios swift uitableview search uisearchbar

I am new to code and I want to make an Search function in my Custom TableViewController. I get an error (Thread 1: signal SIGABRT) when I type (in the search bar) in a letter which correspond to a letter in an list of names (var namen*) I made. When I type in a letter which not correspond to a letter in my list of names I don't get the error. I checked my IBoutlets but they were not the problem. Does someone know how to fix the error? Here's my initial viewcontroller code: (some names are Dutch)

import UIKit

class elementstableviewcontroller: UITableViewController, 
UISearchResultsUpdating{

@IBOutlet var tableview: UITableView!

var namen = ["Waterstof","Helium","Litium","Beryllium","Boor","Koolstof","Stikstof","Zuurstof","Fluor","Neon"]
var afkortingen = ["H","He","Li","Be","B","C","N","O","F","Ne"]
var atoommassas = ["Massa: 1,008","Massa: 4,003","Massa: 6,941","Massa: 9,012","Massa: 10,81","Massa: 12,01","Massa: 14,01","Massa: 16,00","Massa: 19,00","Massa: 20,18"]
var atoomnummers = ["Nummer: 1","Nummer: 2","Nummer: 3","Nummer: 4","Nummer: 5","Nummer: 6","Nummer: 7","Nummer: 8","Nummer: 9","Nummer: 10"]
var ladingen = ["Lading: +1,-1","Lading: 0","Lading: +1","Lading: +2","Lading: +3","Lading: +2,+4,-4","Lading: +1,+2,+3,+4,+5,-1,-2,-3","Lading: -2","Lading: -1","Lading: 0"]
var electronenconfig = ["Config: 1","Config: 2","Config: 2,1","Config: 2,2","Config: 2,3","Config: 2,4","Config: 2,5","Config: 2,6","Config: 2,7","Config: 2,8"]
var searchcontroller : UISearchController!
var resultscontroller = UITableViewController()
var filterednamen = [String]()

override func viewDidLoad() {
    super.viewDidLoad()

    self.resultscontroller.tableView.dataSource = self
    self.resultscontroller.tableView.delegate = self
    self.searchcontroller = UISearchController(searchResultsController: self.resultscontroller)
    self.tableView.tableHeaderView = self.searchcontroller.searchBar
    self.searchcontroller.searchResultsUpdater = self
    self.searchcontroller.dimsBackgroundDuringPresentation = false
    definesPresentationContext = true
}
func updateSearchResults(for searchController: UISearchController) {
    self.filterednamen = self.namen.filter { (naam:String) -> Bool in
        if naam.lowercased().contains(self.searchcontroller.searchBar.text!.lowercased()) {
            return true
        }else{
            return false
        }
    }
    self.resultscontroller.tableView.reloadData()

}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if tableView == self.tableView{
        return  self.namen.count
    }else {
        return self.filterednamen.count
    }
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
    cell.afkorting.text = afkortingen[indexPath.row]
    cell.name.text = namen[indexPath.row]
    cell.atoommassa.text = atoommassas[indexPath.row]
    cell.elektronenconfiguratie.text = electronenconfig[indexPath.row]
    cell.atoomnummer.text = atoomnummers[indexPath.row]
    cell.lading.text = ladingen[indexPath.row]


    if tableView == self.tableView{
            //cell.textLabel?.text = self.namen[indexPath.row]
            cell.name.text = self.namen[indexPath.row]
    }else{
            //cell.textLabel?.text = self.filterednamen[indexPath.row]
            cell.name.text = self.filterednamen[indexPath.row]

    }
    return cell
}

}

And here's my CustomCell code:

import UIKit

class CustomCell: UITableViewCell {

@IBOutlet var elektronenconfiguratie: UILabel!
@IBOutlet var atoomnummer: UILabel!
@IBOutlet var atoommassa: UILabel!
@IBOutlet var name: UILabel!
@IBOutlet var afkorting: UILabel!
@IBOutlet var lading: UILabel!
override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

}

*namen = names and naam = name translated from Dutch to English

2 个答案:

答案 0 :(得分:0)

Try to implement filter functionality in shouldChangeTextIn SearchBar method as given below

func searchBar(_ searchBar: UISearchBar, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

   self.filterednamen = self.namen.filter { (naam:String) -> Bool in

return naam.lowercased().contains(self.searchcontroller.searchBar.text!.lowercased()) 
    }
    self.resultscontroller.tableView.reloadData()

}

答案 1 :(得分:0)

There are several problems with your code.

Firstly, you are creating an IBOutlet of a UITableView unnecessarily. Remove that from your code.

Secondly, you are using that table view for checking if you are searching or not. That is unneccesary, as you want to show search results in the same view controller, so the correct boolean check for that instead is:

!searchcontroller.isActive || searchcontroller.searchBar.text == ""

Lastly, the error occurs exactly because the last issue stated: you are setting the searchResultsController to a phantom table view, so it gets an assertion failure, as it can't find a cell identified "cell".

Here is the fixed code:

import UIKit

class FirstViewController: UITableViewController,
UISearchResultsUpdating{

    var namen = ["Waterstof","Helium","Litium","Beryllium","Boor","Koolstof","Stikstof","Zuurstof","Fluor","Neon"]
    var afkortingen = ["H","He","Li","Be","B","C","N","O","F","Ne"]
    var atoommassas = ["Massa: 1,008","Massa: 4,003","Massa: 6,941","Massa: 9,012","Massa: 10,81","Massa: 12,01","Massa: 14,01","Massa: 16,00","Massa: 19,00","Massa: 20,18"]
    var atoomnummers = ["Nummer: 1","Nummer: 2","Nummer: 3","Nummer: 4","Nummer: 5","Nummer: 6","Nummer: 7","Nummer: 8","Nummer: 9","Nummer: 10"]
    var ladingen = ["Lading: +1,-1","Lading: 0","Lading: +1","Lading: +2","Lading: +3","Lading: +2,+4,-4","Lading: +1,+2,+3,+4,+5,-1,-2,-3","Lading: -2","Lading: -1","Lading: 0"]
    var electronenconfig = ["Config: 1","Config: 2","Config: 2,1","Config: 2,2","Config: 2,3","Config: 2,4","Config: 2,5","Config: 2,6","Config: 2,7","Config: 2,8"]
    var searchcontroller : UISearchController!
    var filterednamen = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.searchcontroller = UISearchController(searchResultsController: nil)
        self.tableView.tableHeaderView = self.searchcontroller.searchBar
        self.searchcontroller.searchResultsUpdater = self
        self.searchcontroller.dimsBackgroundDuringPresentation = false
        definesPresentationContext = true
    }
    func updateSearchResults(for searchController: UISearchController) {
        self.filterednamen = self.namen.filter { (naam:String) -> Bool in
            if naam.lowercased().contains(self.searchcontroller.searchBar.text!.lowercased()) {
                return true
            }else{
                return false
            }
        }

        self.tableView.reloadData()

    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if !searchcontroller.isActive || searchcontroller.searchBar.text == "" {
            return  self.namen.count
        }else {
            return self.filterednamen.count
        }
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
        cell.afkorting.text = afkortingen[indexPath.row]
        cell.name.text = namen[indexPath.row]
        cell.atoommassa.text = atoommassas[indexPath.row]
        cell.elektronenconfiguratie.text = electronenconfig[indexPath.row]
        cell.atoomnummer.text = atoomnummers[indexPath.row]
        cell.lading.text = ladingen[indexPath.row]


        if !searchcontroller.isActive || searchcontroller.searchBar.text == "" {
            //cell.textLabel?.text = self.namen[indexPath.row]
            cell.name.text = self.namen[indexPath.row]
        }else{
            //cell.textLabel?.text = self.filterednamen[indexPath.row]
            cell.name.text = self.filterednamen[indexPath.row]

        }
        return cell
    }

}