0

I have a UISearchBar filter which works well and finds data in my UITableView correctly from my CoreData Database.

It also displays correctly when it doesn't find matching text then disappears when there is a match and displays the data.

My issue is that the no result message shows up when there is no data in the Table View.

I know the cause of the problem since my code does not return the message when the count is more than 0 and since there is no data in the table, it will definitely show the message but I do not know how to resolve this.

Could someone guide me a way so that the no result message only pops up just after searching text then dismisses when the search bar is not in use?

I've also checked countless of related questions on Stack Overflow but none of them fix my needs.

Screenshot

Picture of the issue

As you can see, it is showing the message without even the UISearchBar being used.

Code

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    if coreDataVariable.count > 0 {
        self.tableView.backgroundView = nil
        self.tableView.separatorStyle = .singleLine
        return 1
    }

    let rect = CGRect(x: 0,
                      y: 0,
                      width: self.tableView.bounds.size.width,
                      height: self.tableView.bounds.size.height)
    let noDataLabel: UILabel = UILabel(frame: rect)

    noDataLabel.numberOfLines = 0
    noDataLabel.text = "Query not found.\n\nPlease check your search."
    noDataLabel.textAlignment = NSTextAlignment.center
    self.tableView.backgroundView = noDataLabel
    self.tableView.separatorStyle = .none

    return coreDataVariable.count
}

Here is my Search Bar Function

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

    if !searchText.isEmpty
    {
        var predicate: NSPredicate = NSPredicate()

        predicate = NSPredicate(format: "attriubteName1 contains[c] '\(searchText)' OR attriubteName2 contains[c] '\(searchText)'")
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
        let managedObjectContext = appDelegate.persistentContainer.viewContext
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "EntityName")
        fetchRequest.predicate = predicate
        do
        {
            coreDataVariable = try managedObjectContext.fetch(fetchRequest) as! [NSManagedObject] as! [ObjectName]
        }
        catch let error as NSError
        {
            let alert = UIAlertController(title: "Cannot Search Data", message: "Error searching saved data. Please reinstall ObjectName Saver if problem persists.", preferredStyle: UIAlertController.Style.alert)

            let okAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.cancel)
            {
                UIAlertAction in
                alert.removeFromParent()
            }
            alert.addAction(okAction)

            self.present(alert, animated: true, completion: nil)

            print("Could not fetch. \(error)")
        }
    }
    else
    {
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
        let managedObjectContext = appDelegate.persistentContainer.viewContext
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ObjectName")
        do
        {
            coreDataVariable = try managedObjectContext.fetch(fetchRequest) as! [ObjectName]
        }
        catch
        {
            let alert = UIAlertController(title: "Cannot Load Data", message: "Error loading saved data. Please app if problem persists.", preferredStyle: UIAlertController.Style.alert)

            let okAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.cancel) {
                UIAlertAction in
                alert.removeFromParent()
            }
            alert.addAction(okAction)

            self.present(alert, animated: true, completion: nil)

            print("Error loading data")
        }

    }
    table.reloadData()
}
Broski
  • 75
  • 9

2 Answers2

1

Simple logic can be integrated here according your problem

var isSearchActive = false // bool variable

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
{
  if self.searchBar.text == ""
  {
        isSearchActive = false 
       //--               
  }
  else
   {
        isSearchActive = true
   }

    self.tableView.reloadData()
  }

 //logic  this  data source method
 func numberOfSections(in tableView: UITableView) -> Int
 {
 if coreDataVariable.count > 0 {
   self.tableView.backgroundView = nil
   self.tableView.separatorStyle = .singleLine
    return 1
 }
 else 
 { 
    if isSearchActive == true
    {
       // -- Make UIlabel here
    }
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection  section: Int) -> Int
{
return coreDataVariable.count
}
Lalit kumar
  • 1,797
  • 1
  • 8
  • 14
0

It seems your coreDataVariable.count is 0 when there is no data. Hence there is not row and your label shows what it is told to show "Query not found.\n\nPlease check your search." I believe coreDataVariable contains all data before being searched. You also need some sorted filteredDat

Without seeing at your searchBar code:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    if searchController.isActive &&  searchController.searchBar.text != ""{
        // check your filtered data count here and if it is 0, show your label
        // Do the logic and find how many rows you need
    }
}

Rule of thumb, when tableView has SearchBar then NumberOfSection, NumebrOfRow, CellForRow need:

if searchController.isActive &&  searchController.searchBar.text != ""{
        //Your logic here
}

UPDATE November 7,2019: somewhere in the code define this

let searchController = UISearchController(searchResultsController: nil)

make sure your class conforms to UISearchResultsUpdating and UISearchBarDelegate Also this one may help https://stackoverflow.com/a/28997222/1200543

  • I'm getting a "'Use of unresolved identifier 'searchController'" error, where am I meant to declare it or shouldn't it be already in the UISearchBarDelegate class as already referenced? – Broski Nov 07 '19 at 05:21