Add a Searchbar on TableView but no response - ios

Referring to shrikar's work - ://shrikar.com/swift-ios-tutorial-uisearchbar-and-uisearchbardelegate/, I try to build a searchbar in table view. The tableview works fine when no adding search text. The problem is no response and error message when add search text.
I wonder something wrong. Could anybody help us? Thanks.
import UIKit
import SDWebImage
class ArticleListViewController: UITableViewController, UISearchBarDelegate{
#IBOutlet weak var searchBar: UISearchBar!
var searchActive : Bool = false
var filtered = [Article]()
var articles = [Article](){
didSet{
DispatchQueue.main.async{
self.tableView.reloadData()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
downLoadLatestArticles()
}
func downLoadLatestArticles(){
Article.downLoadItem { (articles, error) in
if let error = error {
print("fail \(error)")
return
}
if let articles = articles {
self.articles = articles
}
}
}
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
searchActive = true;
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
searchActive = false;
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchActive = false;
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchActive = false;
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
if(searchText == " "){
searchActive = false
}else{
filtered = articles.filter ({ (article_f) -> Bool in
let tmp: String = article_f.name
let range = tmp.range(of:searchText, options: String.CompareOptions.caseInsensitive)
return range != nil
})
if(filtered.count == 0){
searchActive = false;
} else {
searchActive = true;
}
}
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchActive) {
return filtered.count
}
return articles.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ListTableCell", for: indexPath) as! ListTableCell
var article : Article
if(searchActive){
article = filtered[indexPath.row]
}
else{
article = articles[indexPath.row]
}
cell.nameLabel?.text = article.name
cell.locationLabel?.text = article.location
cell.photoView?.sd_setImage(with: article.image_URL)
return cell
}
}

Related

Search Bar is not filtering properly

I have a search bar in my tableview, but when I initially click on the search bar, the results disappear. If I segue to another controller, and come back, the search bar works fine, with all the results showing when the bar is clicked.
Here is the code:
#IBOutlet weak var toolTable: UITableView!
#IBOutlet weak var searchForTool: UISearchBar!
var searchActive : Bool = false
{
didSet {
if searchActive != oldValue {
toolTable?.reloadData()
}
}
}
typealias Item = (data: String, identity: String)
var filtered: [Item] = []
var items: [Item] = [
(data: " Data1", identity: "A"),
(data: " Data2", identity: "B")
]
override func viewDidLoad() {
super.viewDidLoad()
toolTable.delegate = self
toolTable.dataSource = self
searchForTool.delegate = self
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchActive = true
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
searchActive = false
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchActive = false
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchActive = false
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filtered = items.filter { item in
item.data.localizedCaseInsensitiveContains(searchText)
}
searchActive = !filtered.isEmpty
self.toolTable.reloadData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchActive) {
return filtered.count
}
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
if(searchActive){
cell.toolLabel.text = filtered[indexPath.row].data
} else {
cell.toolLabel.text = items[indexPath.row].data
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vcName: String
if searchActive {
vcName = filtered[indexPath.row].identity
} else {
vcName = items[indexPath.row].identity
}
let viewController = storyboard?.instantiateViewController(withIdentifier: vcName)
self.navigationController?.pushViewController(viewController!, animated: true)
}
I'm sure its some simple solution, I'm just overlooking it.
Any help would be greatly appreciated.
Reading your code I see that: searchBarTextDidBeginEditing sets searchActive to true. The data will be reloaded as per the code in didSet. tableView:numberOfRowsInSection is then called and filtered.count is returned, meaning 0 as it's empty. That's why results disappear.

search bar in ios swift

I want to use search bar in my app.I am trying to use it but exceptions are coming . I have got an array of dictionary called member [[String:Anyobject]] and from this i have taken out the name and stored into an array data of type string and it is not working.
Here is my code :
import UIKit
class hcbaViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate {
#IBOutlet var searchbar: UISearchBar!
#IBOutlet var tableview: UITableView!
var member = [[String:AnyObject]]()
var members = [String:AnyObject]()
var searchActive = true
var filtered:[String] = []
var data: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
print(data)
print("________-----------________----------")
print(member)
// Do any additional setup after loading the view.
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchActive = true
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
searchActive = false
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchActive = false
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchActive = false
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filtered = data.filter({ (text) -> Bool in
let tmp:NSString = text as NSString
let range = tmp.range(of: searchText, options: NSString.CompareOptions.caseInsensitive)
return range.location != NSNotFound
})
if (filtered.count == 0){
searchActive = false
}
else{
searchActive = true
}
self.tableview.reloadData()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "MemberDirectory"
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return member.count
if(searchActive){
return filtered.count
}
else{
return data.count
}
// return member.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell",for: indexPath)
var display = member[indexPath.row]
cell.textLabel?.text = display["Name"] as! String?
cell.detailTextLabel?.text = display["email"] as? String
let n = display["Name"] as! String
data.append(n)
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! hcbadetailViewController
vc.kk = members
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
members = member[indexPath.row]
self.performSegue(withIdentifier: "bye", sender: nil)
}
You can try this...
class SearchNew: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, GADInterstitialDelegate{
var SearchBarValue:String!
var searchActive : Bool = false
var data : NSMutableArray!
var filtered:NSMutableArray!
#IBOutlet var searchBar: UISearchBar!
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.searchBar.showsCancelButton = false
tableView.tableFooterView = UIView(frame: CGRectZero)
/* Setup delegates */
tableView.delegate = self
tableView.dataSource = self
searchBar.delegate = self
self.searchBar.delegate = self
data = []
filtered = []
self.getData()
} //-----viewDidLoad closed------
func getData()
{
//insert member data within data array
data.addObject(member)
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchActive = true
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
searchActive = false
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchActive = false;
searchBar.text = nil
searchBar.resignFirstResponder()
tableView.resignFirstResponder()
self.searchBar.showsCancelButton = false
tableView.reloadData()
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchActive = false
}
func searchBarShouldEndEditing(searchBar: UISearchBar) -> Bool {
return true
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
self.searchActive = true;
self.searchBar.showsCancelButton = true
filtered.removeAllObjects()
dispatch_to_background_queue
{
for xdata in self.data
{
let nameRange: NSRange = xdata.rangeOfString(searchText, options: [NSStringCompareOptions.CaseInsensitiveSearch ,NSStringCompareOptions.AnchoredSearch ])
if nameRange.location != NSNotFound{
self.filtered.addObject(xdata)
}
}//end of for
self.dispatch_to_main_queue {
/* some code to be executed on the main queue */
self.tableView.reloadData()
} //end of dispatch
}
}
func dispatch_to_main_queue(block: dispatch_block_t?) {
dispatch_async(dispatch_get_main_queue(), block!)
}
func dispatch_to_background_queue(block: dispatch_block_t?) {
let q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(q, block!)
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchActive) {
return filtered.count
}else{
return data.count
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "showDetailView") {
if let destination=segue.destinationViewController as? DetailViewController{
let path=tableView.indexPathForSelectedRow
let cell=tableView.cellForRowAtIndexPath(path!)
destination.passedValue=(cell?.textLabel?.text)
}
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
searchBar.resignFirstResponder()
searchBar.endEditing(true)
self.view.endEditing(true)
self.searchBar.showsCancelButton = false
self.searchBar.text=""
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! as UITableViewCell;
if(searchActive){
cell.textLabel?.text = filtered[indexPath.row] as! NSString as String
} else {
cell.textLabel?.text = data[indexPath.row]as! NSString as String
}
return cell;
}
}
Hope it helps you.
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate {
#IBOutlet var tblview: UITableView!
#IBOutlet var searchview: UISearchBar!
var data:[String] = ["Dev","Hiren","Bhagyashree","Himanshu","Manisha","Trupti","Prashant","Kishor","Jignesh","Rushi"]
var filterdata:[String]!
override func viewDidLoad() {
super.viewDidLoad()
tblview.dataSource = self
searchview.delegate = self
filterdata = data
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filterdata.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tblview.dequeueReusableCell(withIdentifier: "cell", for: indexPath)as!TableViewCell1
if filterdata.count != 0
{
cell.textview.text = filterdata[indexPath.row]
}
else{
cell.textview.text = data[indexPath.row]
}
return cell
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
// filterdata = searchText.isEmpty ? data : data.filter {(item : String) -> Bool in
filterdata = searchText.isEmpty ? data : data.filter { $0.contains(searchText) }
//return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
tblview.reloadData()
}
let searchController = UISearchController(searchResultsController: nil)
navigationItem.hidesSearchBarWhenScrolling = true
navigationItem.searchController = searchController
Replace this method with your TableView's method
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchActive){
return filtered.count
}
else{
return data.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell",for: indexPath)
var display = searchActive == true ? filtered[indexPath.row] :
data[indexPath.row]
cell.textLabel?.text = display["Name"] as! String?
cell.detailTextLabel?.text = display["email"] as? String
let n = display["Name"] as! String
data.append(n)
return cell
}

Swift Search Bar with Multiple Data

I have 5 labels that receive data from an array of SQL Query, in each cell on a tableView. I want to implement the search bar on it. Search bar should search through 1 specific label's data. it's working and filtering that specific label but when it's filtered, other 4 labels won't update and they are not changing at all. I can't figure it out. Since I have only 1 filtered data from search bar entry, I don't know how should I filter others.
Thanks
EDIT: Still can't figure it out about classes and adding data and i have an error of
"Value of type '[String]' has no member
'localizedCaseInsensitiveContains'"
on searchbar function
import UIKit
class TableViewController: UITableViewController, UISearchBarDelegate, UISearchDisplayDelegate {
var data:[MyData] = []
#IBOutlet weak var searchBar: UISearchBar!
var searchActive : Bool = false
var filtered:[MyData] = []
#IBAction func sqlExecute(_ sender: AnyObject) {
var client = SQLClient()
client.connect("sql_ip", username: "username", password: "password", database: "database") {
success in
if success {
client.execute("sql query") {
result in
for table in result as Any as! NSArray {
for row in table as! NSArray {
for column in row as! NSDictionary {
if column.key as! String == "data1" {
MyData.init(data1: "\(column.value)")
} else if column.key as! String == "data2" {
MyData.init(data2: column.value as! Double)
} else if column.key as! String == "data3" {
MyData.init(data3: "\(column.value)")
} else if column.key as! String == "data4" {
MyData.init(data4: "\(column.value)")
} else if column.key as! String == "data5" {
MyData.init(data5: "\(column.value)")
}
}
}
}
client.disconnect()
self.tableView.reloadData()
}
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
searchBar.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchActive) {
return filtered.count
} else {
return data.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "segue", for: indexPath)
if(searchActive) {
cell.label1.text = "\(filtered[indexPath.row])"
cell.label2.text = "\(filtered[indexPath.row])"
cell.label3.text = "\(filtered[indexPath.row])"
cell.label4.text = "\(filtered[indexPath.row])"
cell.label5.text = "\(filtered[indexPath.row])"
} else {
cell.label1.text = "\(data[indexPath.row])"
cell.label2.text = "\(data[indexPath.row])"
cell.label3.text = "\(data[indexPath.row])"
cell.label4.text = "\(data[indexPath.row])"
cell.label5.text = "\(data[indexPath.row])"
}
cell.backgroundColor = UIColor.clear
cell.selectionStyle = UITableViewCellSelectionStyle.none
return cell
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchActive = true;
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
searchActive = false;
self.searchBar.endEditing(true)
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchActive = false;
self.searchBar.endEditing(true)
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchActive = false;
self.searchBar.endEditing(true)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filtered = data.filter { $0.data1.localizedCaseInsensitiveContains(searchText) }
if(filtered.count == 0){
searchActive = false;
} else {
searchActive = true;
}
self.tableView.reloadData()
}
This is the class file:
import Foundation
class MyData {
var data1 = [String]()
var data2 = [Double]()
var data3 = [String]()
var data4 = [String]()
var data5 = [String]()
init(data1: String) {
self.data1.append(data1)
}
init(data2: Double) {
self.data2.append(data2)
}
init(data3: String) {
self.data3.append(data3)
}
init(data4: String) {
self.data4.append(data4)
}
init(data5: String) {
self.data5.append(data5)
}
}
Your problem is you have five different Array instead of that you need to have single Array of type Dictionary or maybe custom Struct/class. It is batter if you use struct/class like this.
class MyData {
var data1: String!
var data2: Double!
var data3: String!
var data4: String!
var data5: String!
init(data1: String, data2: Double, data3: String, data4: String, data5: String) {
self.data1 = data1
self.data2 = data2
self.data3 = data3
self.data4 = data4
self.data5 = data5
}
}
Now instead of having five different array and one for filter create two Array of type [MyData] one of them is used for showing filterData and use that with tableView methods and filter it like this.
Create object of MyData using init method it and append its to the data Array then filter your in searchBar delegate like this.
filtered = data.filter { $0.data1.localizedCaseInsensitiveContains(searchText) }
The above filter will search in data array and return all objects thats property data1 contains searchText.
Your whole code would be like this
import UIKit
class TableViewController: UITableViewController, UISearchBarDelegate, UISearchDisplayDelegate {
var data:[MyData] = []
#IBOutlet weak var searchBar: UISearchBar!
var searchActive : Bool = false
var filtered:[MyData] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
searchBar.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchActive) {
return filtered.count
} else {
return data.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "segue", for: indexPath)
if(searchActive) {
cell.label1.text = filtered[indexPath.row].data1
cell.label2.text = filtered[indexPath.row].data2
cell.label3.text = filtered[indexPath.row].data3
cell.label4.text = "\(filtered[indexPath.row].data4) ₺"
cell.label5.text = filtered[indexPath.row].data5
} else {
cell.label1.text = data[indexPath.row].data1
cell.label2.text = data[indexPath.row].data2
cell.label3.text = data[indexPath.row].data3
cell.label4.text = "\(data[indexPath.row].data4) ₺"
cell.label5.text = data[indexPath.row].data5
}
cell.backgroundColor = UIColor.clear
cell.selectionStyle = UITableViewCellSelectionStyle.none
return cell
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchActive = true;
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
searchActive = false;
self.searchBar.endEditing(true)
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchActive = false;
self.searchBar.endEditing(true)
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchActive = false;
self.searchBar.endEditing(true)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filtered = data.filter { $0.data1.localizedCaseInsensitiveContains(searchText) }
if(filtered.count == 0){
searchActive = false;
} else {
searchActive = true;
}
self.tableView.reloadData()
}
}
Edit: You need to use single array like this way.
for table in result as Any as! NSArray {
for row in table as! NSArray {
if let dic = row as? [String : Any] {
let data1 = dic["data1"] as! String
let data2 = dic["data2"] as! Double
let data3 = dic["data3"] as! String
let data4 = dic["data4"] as! String
let data5 = dic["data5"] as! String
let newData = MyData(data1: data1, data2: data2, data3: data3, data4: data4, data5: data5)
self.data.append(newData)
}
}
}
self.tableView.reloadData()
First you have to make a global array then in search bar delegates sort it .
extension HVUserLisitingViewController : UITableViewDelegate , UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filterUser.count
}
}
extension HVUserLisitingViewController : UISearchBarDelegate {
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
return true
}
func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
return true }
func searchBar(_ searchBar: UISearchBar, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
return true
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { // called when text changes (including clear)
webserviceSearchBy(text: searchBar.text!)
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
filterUser.removeAll()
filterUser = users
tableview.reloadData()
}
func webserviceSearchBy(text : String) {
if text.lowercased().count == 0 {
filterUser.removeAll()
filterUser = users
tableview.reloadData()
return
}
filterUser.removeAll()
filterUser = users.filter({ (user) -> Bool in
if user.username.lowercased().range(of:text.lowercased()) != nil {
return true
}
return false
})
tableview.reloadData()
}
}

Why my search bar is not working?

I have tried to solve this for a couple of hours. I am a newbie in IOS and want to develop a bucket list with a search bar. The codes have no problem in compilation but when i make input in the search bar, it won't show any search result. I don't know where the problem is.
btw: I have two suspects:
1. I tried to print the status, and it seems the searchBar is never active. How to open it?
2. Does it have anything to do with var missions' data
type as Mission? It is something I am not familiar with.
Please see the following codes:
import UIKit
class BucketListViewController:UITableViewController, MissionDetailsViewControllerDelegate, MissionEditViewControllerDelegate, UISearchBarDelegate{
var searchController = UISearchController(searchResultsController: nil)
#IBOutlet weak var searchBar: UISearchBar!
var searchActive : Bool = false
var filtered:[String] = []
var missions:[String] = ["Sky diving", "Live in Hawaii"]
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
self.searchDisplayController!.searchResultsTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
}
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
searchActive = true;
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
searchActive = false;
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchActive = false;
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchActive = false;
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
filtered = missions.filter({ (text) -> Bool in
let tmp: NSString = text
let range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
return range.location != NSNotFound
})
if(filtered.count == 0){
searchActive = false;
} else {
searchActive = true;
}
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// dequeue the cell from our storyboard
let cell = tableView.dequeueReusableCellWithIdentifier("MyCell")!
if(searchActive){
print("search active!")
cell.textLabel?.text = filtered[indexPath.row]
} else {
cell.textLabel?.text = missions[indexPath.row]
}
return cell
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchActive){
return filtered.count
} else {
return missions.count
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "AddNewMission" {
let navigationController = segue.destinationViewController as! UINavigationController
let controller = navigationController.topViewController as! MissionDetailsViewController
controller.delegate = self
}
if segue.identifier == "EditMission" {
let navigationController = segue.destinationViewController as! UINavigationController
let controller = navigationController.topViewController as! MissionEditViewController
controller.delegate = self
}
}
func missionDetailsViewController(controller: MissionDetailsViewController, didFinishAddingMission mission: String) {
dismissViewControllerAnimated(true, completion: nil)
missions.append(mission)
tableView.reloadData()}
func missionEditViewController(controller: MissionEditViewController, didFinishEditingMission mission: String, atIndexPath indexPath: Int) {
dismissViewControllerAnimated(true, completion: nil)
missions[indexPath] = mission
tableView.reloadData()
}
}
From the project you have shared there is a problem in your cellForRowAtIndexPath method.
replace
cell.textLabel?.text = filtered[indexPath.row] as? String
with
cell.textLabel?.text = filtered[indexPath.row].details
And it will work fine.
Your complete code will be:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// dequeue the cell from our storyboard
let cell = tableView.dequeueReusableCellWithIdentifier("MissionCell")!
// if the cell has a text label, set it to the model that is corresponding to the row in array
if(searchActive){
print("search active!")
cell.textLabel?.text = filtered[indexPath.row].details
} else {
cell.textLabel?.text = missions[indexPath.row].details
}
return cell
}

Issues setting up searchdisplaycontroller with tableview - Swift

I'm trying to setup the searchdisplaycontroller up for my tableview and am experiencing a couple of issues when declaring my iboutlet for the tableview itself. Attached is a screenshot as well as my code. Any insight much appreciated.
Code Errors Img
import UIKit
class DataTableExercisesTableViewController: UITableViewController, UISearchBarDelegate {
var exercises = ["Abs", "Arms", "Back", "Chest", "Legs", "Shoulders", "Triceps"]
var searchActive : Bool = false
#IBOutlet var tableView: UITableView!
#IBOutlet weak var searchBar: UISearchBar!
var filtered:[String] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView()
tableView.delegate = self
tableView.dataSource = self
searchBar.delegate = self
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(searchActive) {
return filtered.count
}
return exercises.count;
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! as UITableViewCell;
if(searchActive){
cell.textLabel?.text = filtered[indexPath.row]
} else {
cell.textLabel?.text = exercises[indexPath.row];
}
return cell;
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
searchActive = true;
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
searchActive = false;
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchActive = false;
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchActive = false;
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
filtered = exercises.filter({ (text) -> Bool in
let tmp: NSString = text
let range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
return range.location != NSNotFound
})
if(filtered.count == 0){
searchActive = false;
} else {
searchActive = true;
}
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
Have you tried removing the IBoutlet completely? (Both from storyboard connections and in your code). I think this will solve your issue.

Resources