3

I have an array of Studios. Each studio, has a property called studioName.

I need my searchfield to filter the studios, based on the studioName, applied to the searchfield by the user.

Here's my current code:

var studios = [Studio]()
var filteredStudios = [Studio]()
var studiosToDisplay = [Studio]()

func updateSearchResultsForSearchController(searchController: UISearchController) {
    let searchText = searchController.searchBar.text

    print("SEARCH TEXT: \(searchText)")

    if searchText == nil || searchText!.isEmpty {
        studiosToDisplay = studios
        self.resultTableView.reloadData()
        NSNotificationCenter.defaultCenter().postNotificationName("showResultsBeforeSearchingNotification", object: nil) //Calls SearchVC
    } else {
        studiosToDisplay.removeAll()
        let searchPredicate = NSPredicate(format: "studioName CONTAINS[c] %@", searchText!)
        let array = (self.studios as NSArray).filteredArrayUsingPredicate(searchPredicate)
        studiosToDisplay = array as! [Studio]
        self.resultTableView.reloadData()
    }
}

It's just not working wight, right now.. It filters, but I end up with the same Studio left each time, no matter what I put in the searchfield.

I guess I need to make the predicate know, that it has to look at the single object in the array, each time. But I just can't figure out how. I tried to add "ANY" in the format, but that crashes my app.

2
  • You should tag your question properly as it seems that you are using Swift 2 (I recommend updating your Xcode to the latest Xcode available at the APP Store) Commented Apr 23, 2017 at 13:51
  • On a side note: checking for nil with searchText == nil, then force unwrapping (searchText!) is really bad practice Commented Apr 23, 2017 at 15:45

2 Answers 2

9

This is unnecessarily complex. There's no need for NSPredicate here.

var studios = [Studio]()
var filteredStudios = [Studio]()
var studiosToDisplay = [Studio]()

func updateSearchResultsForSearchController(searchController: UISearchController) {
    let searchText = searchController.searchBar.text

    print("SEARCH TEXT: \(searchText)")

    if let searchText = searchText, !searchText.isEmpty {
        studiosToDisplay = studios.filter{ $0.studioName.contains(searchText) }
    }
    else {
        studiosToDisplay = studios
        NSNotificationCenter.defaultCenter().postNotificationName("showResultsBeforeSearchingNotification", object: nil) //Calls SearchVC
    }

    self.resultTableView.reloadData()
}
Sign up to request clarification or add additional context in comments.

Comments

1

Thanks to @Alexander .. Here's the code I ended up using:

func updateSearchResultsForSearchController(searchController: UISearchController) {

    let searchText = searchController.searchBar.text

    if let searchText = searchText {
        if !searchText.isEmpty {
            self.studiosToDisplay = self.studios.filter { $0.studioName!.containsString(searchText) }
            for studio in self.studiosToDisplay {
                print("\(studio.studioName!)")
            }
        }
        else {
            self.studiosToDisplay = self.studios
            NSNotificationCenter.defaultCenter().postNotificationName("showResultsBeforeSearchingNotification", object: nil) // Calls SearchVC
        }
    }

    self.resultTableView.reloadData()

}

I figured out, that my former code, with the NSPredicate actually was functional - I was just presenting the wrong array in my tableview.. Oops.. But now it works, and I stick to the more simple code. Don't know why I didn't think of using the $0-function :) .. Anyway, thanks!

1 Comment

You can use a guard statement to bind searchText without that extra level of indentation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.