Reputation: 24116
I am learning to implement TableView with Search Bar and data filtering. So, I have the following in my storyboard
:
My UITableViewController
is connected to the following SearchTableViewController.swift
class like this:
import UIKit
class SearchTableViewController: UITableViewController, UISearchResultsUpdating {
// table view controller properties
let appleProducts = ["Mac", "iPhone", "Apple Watch", "iMac", "iPad"]
var filteredAppleProducts = [String]()
var resultSearchController = UISearchController()
override func viewDidLoad() {
super.viewDidLoad()
// Configure result search controller
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.resultSearchController.searchBar.placeholder = "Search Products"
self.tableView.tableHeaderView = self.resultSearchController.searchBar
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (self.resultSearchController.active) {
return self.filteredAppleProducts.count
} else {
return self.appleProducts.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
if (self.resultSearchController.active) {
cell.textLabel?.text = self.filteredAppleProducts[indexPath.row]
} else {
cell.textLabel?.text = self.appleProducts[indexPath.row]
}
return cell
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
self.filteredAppleProducts.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
let resultArray = (self.appleProducts as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredAppleProducts = resultArray as! [String]
self.tableView.reloadData()
}
}
This runs fine and filtering is working as expected:
However, when the app is running in the simulator, I get the following warning in the debug window:
2015-09-07 00:02:46.116 TableViewSearch[2415:68217] Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior ()
Any ideas how to fix this?
Upvotes: 3
Views: 8597
Reputation: 73
I spent all day to understand this problem too... Some said it's related to Navigation Controller issue and others said it's a glitch. Although this may not be the correct answer, hope I can give some hint. If you think it's not a correct approach, let me know. Thanks. My case is as follows instead (because of a different design, I think.)
var resultSearchController: UISearchController!()
Then, I had to add below.
self.resultSearchController.loadViewIfNeeded()
Upvotes: 6
Reputation: 523
Just change following line
var resultSearchController = UISearchController()
to following line
var resultSearchController:UISearchController!
Your rest of the code is ok. Only that one change is required.
If you want to see detailed explanation then check my tutorial on UISearchController
Upvotes: 1