How to return multiple values in swift - ios

I'm starter in swift.
I create tableview and get data from jsonFile to show text and picture.
Then I want to add searchBar on tableview but have problem.
import UIKit
class EpisodesTableViewController: UITableViewController
{
var episodes = [Episode]()
var names = [Episode]()
let searchController = UISearchController(searchResultsController: nil)
var filteredNames = [Episode]()
func filterContentForSearchText(searchText: String) {
filteredNames = self.names.filter { name in
return name.title!.lowercaseString.containsString(searchText.lowercaseString)
}
tableView.reloadData()
}
override func viewDidLoad()
{
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
tableView.setContentOffset(CGPoint(x: 0, y: searchController.searchBar.frame.size.height), animated: false)
tableView.estimatedRowHeight = tableView.rowHeight
tableView.rowHeight = UITableViewAutomaticDimension
tableView.separatorStyle = .None
self.episodes = Episode.downloadAllEpisodes()
self.tableView.reloadData()
}
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if searchController.active && searchController.searchBar.text != ""{
return filteredNames.count
}else{
return names.count
}
return episodes.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("Episode Cell", forIndexPath: indexPath) as! EpisodeTableViewCell
let episode = self.episodes[indexPath.row]
let data: Episode
if searchController.active && searchController.searchBar.text != "" {
data = filteredNames[indexPath.row]
}
else {
data = names[indexPath.row]
}
let titleName = data.title!
cell.episode = episode
cell.textLabel?.text = titleName
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "SendData"{
if let detailPage = segue.destinationViewController as? detailEpisodeViewController {
if let indexpath = tableView.indexPathForSelectedRow {
let episode = episodes[indexpath.row]
detailPage.episode = episode
}
}
}
}
}
extension EpisodesTableViewController: UISearchResultsUpdating {
func updateSearchResultsForSearchController(searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
}
this my code.
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if searchController.active && searchController.searchBar.text != ""{
return filteredNames.count
}else{
return names.count
}
return episodes.count
}
When I return filteredNames and names interface just show seachbar. If I return filtered names and episodes show error index out of range.
I don't know How to fix that.

If you want to return two values just return a touple like so:
return (DataType, DataType)
so this could be
func returnTouple() -> (String, AnyObject) {
return ("Hello World", 1)
}
then you would access it like so:
let (myString, myObject) = returnTouple()
and myString == "Hello World"
You could also access both throught .0 and .1 like returnTouple().0 == "Hello World"
Next,
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.active && searchController.searchBar.text != "" {
return filteredNames.count
} else {
return names.count
}
return episodes.count
}
This function shouldn't work. You have an if {} else {} with a return statement in both sections. Unless you said if {} else if {} this makes the thrid return statement impossible to hit so it shouldn't be there.

Related

SearchController filtering problem in TableView

I've next model:
struct HashTags {
var title = ""
var tags = [String]()
}
and I try use UISearchController for seach text in tags array.
I impelemented UISearchController in my TableViewController:
class TagsController: UITableViewController {
var hashtags = [HashTags]()
var filtered = [HashTags]()
let searchController = UISearchController(searchResultsController: nil)
var searchBarIsEmpty: Bool {
guard let text = searchController.searchBar.text else { return false }
return text.isEmpty
}
var isFiltering: Bool {
return searchController.isActive && !searchBarIsEmpty
}
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search"
navigationItem.searchController = searchController
definesPresentationContext = true
}
override func numberOfSections(in tableView: UITableView) -> Int {
if isFiltering {
return filtered.count
}
return hashtags.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if isFiltering {
return filtered[section].title
}
return hashtags[section].title
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering {
return filtered[section].tags.count
}
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Tags", for: indexPath)
var item = HashTags()
if isFiltering {
item = filtered[indexPath.section]
} else {
item = hashtags[indexPath.section]
}
let tags = item.tags
cell.textLabel?.text = tags.joined(separator: ", ")
return cell
}
}
extension TagsController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
func filterContentForSearchText(_ searchText: String) {
filtered = hashtags.filter({ (hashtag: HashTags) -> Bool in
return hashtag.tags.contains(searchText.lowercased())
})
tableView.reloadData()
}
}
But it doesn't work as it should and when I start type text I receive blank screen. I need UISearchController work correctctly and search for text in HashTags tags arrays, showing correct number of sections and rows.

Random grey bar appears on top of ViewController in iOS (swift)

I am making an app currently and on the main screen where I load multiple items from Parse, I see a weird grey bar. I don't know where this bar came from as it does not show up on the storyboard and I don't know how to fix it. It never was a problem until it randomly recently showed up. Here is the code for that ViewController.
import UIKit
import Parse
import ParseUI
import Kingfisher
class HomeTableViewController: PFQueryTableViewController
{
override func viewDidLoad ()
{
super.viewDidLoad()
setTitle()
self.navigationController?.isNavigationBarHidden = true
self.navigationController?.navigationBar.setHeight(0.0)
// self.tableView.scrollsToTop = true
// self.tableView.scrollToNearestSelectedRow(at: UITableViewScrollPosition.bottom, animated: false)
// self.tableView.scrollToNearestSelectedRow(at: UITableViewScrollPosition.top, animated: true)
}
func setTitle()
{
var parentView = self.parent
while parent != nil
{
if let menu = parentView as? CucuMenuController
{
// menu.setTitleForLabel("Cucus")
menu.setTitleForLabel("")
break
}
parentView = parentView?.parent
}
}
var firstTime = true
var totalArticles = 0
let appDel = UIApplication.shared.delegate as! AppDelegate
required init!(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
setupHomefeed()
}
func setupHomefeed()
{
// This runs before didFinishLoadingWithOptions
self.parseClassName = "Article"
self.pullToRefreshEnabled = true
self.paginationEnabled = true
self.objectsPerPage = 10
self.loadingViewEnabled = true
}
override func objectsDidLoad(_ error: Error?)
{
super.objectsDidLoad(error)
if firstTime
{
firstTime = false
self.loadObjects()
self.tableView.reloadData()
}
else
{
PFObject.pinAll(inBackground: self.objects)
}
}
override func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
override func viewDidAppear(_ animated: Bool)
{
navigationController?.isNavigationBarHidden = false
if PFUser.current() == nil || PFUser.current()!["name"] == nil
{
let viewController = storyboard!.instantiateViewController(withIdentifier: "LoginController")
UIApplication.shared.keyWindow?.rootViewController = viewController
}
else if UserDefaults.standard.bool(forKey: "showDemo")
{
self.performSegue(withIdentifier: "detailSegue", sender: self)
}
else
{
self.loadObjects()
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if self.objects!.count < totalArticles && self.objects!.count > 0
{
return self.objects!.count + 1
}
return self.objects!.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
if indexPath.row == self.objects?.count
{
return 70.0
}
else
{
return 221.5
}
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0.0
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 0.0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as UITableViewCell!
if indexPath.row == self.objects!.count
{
return tableView.dequeueReusableCell(withIdentifier: "loadCell") as UITableViewCell!
}
if (indexPath.row > self.objects!.count)
{
return cell!
}
let imageView = cell?.viewWithTag(200) as! UIImageView
let titleText = cell?.viewWithTag(101) as! UILabel
let timeLabel = cell?.viewWithTag(102) as! UILabel
let newImage = cell?.viewWithTag(100) as! UIImageView
let diffImage = cell?.viewWithTag(300) as! UIImageView
let scoreLabel = cell?.viewWithTag(301) as! UILabel
let catLabel = cell?.viewWithTag(103) as! UILabel
let article = Article(parseData: self.objects![indexPath.row])
titleText.text = article.title
timeLabel.text = article.duration
catLabel.text = article.category.uppercased()
let hasRead = UserController.hasReadArticle(article.objectId)
newImage.isHidden = hasRead
if hasRead
{
let score = UserController.getScoreForArticle(article.objectId)
scoreLabel.text = NSString(format: "YOUR SCORE: %.0f", score) as String
var performance = "hard"
if score >= article.idealScore { performance = "easy" }
else if score * 2 >= article.idealScore { performance = "medium" }
diffImage.image = UIImage(named: performance + "ScoreTag")
if UserController.getPlayableForArticle(article.objectId) {
cell?.isUserInteractionEnabled = true
}
}
else
{
scoreLabel.text = NSString(format: "AVG. SCORE: %.0f", article.idealScore) as String
diffImage.image = UIImage(named: article.difficulty.lowercased() + "ScoreTag")
}
//Image
let resource = ImageResource(downloadURL: article.getImageURL(), cacheKey: article.objectId)
imageView.kf.setImage(with: resource)
UIHelper.addShadowToHomeCell((cell?.viewWithTag(1)!)!)
return cell!
}
var selectedIndex = -1
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if indexPath.row == self.objects!.count
{
self.loadNextPage()
}
else
{
selectedIndex = indexPath.row
self.performSegue(withIdentifier: "detailSegue", sender: self)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "detailSegue"
{
let dest = segue.destination as? ArticlePreviewViewController
if UserDefaults.standard.bool(forKey: "showDemo")
{
dest?.article = DemoArticle().article
}
else
{
dest?.article = Article(parseData: self.objects![selectedIndex])
}
}
NotificationCenter.default.post(name: Notification.Name(rawValue: "CUCU_START"), object: nil)
}
override func queryForTable() -> PFQuery<PFObject>
{
let q = PFQuery(className: "Article").whereKey("releaseDate", lessThanOrEqualTo: Date()).whereKey("validated", equalTo: true)
if firstTime
{
q.fromLocalDatastore()
}
else
{
let mods = PFQuery(className: "Question").whereKey("article", matchesQuery: q)
mods.findObjectsInBackground
{
(objects, err) -> Void in
PFObject.pinAll(inBackground: objects)
}
}
print(firstTime)
totalArticles = q.countObjects(nil)
q.order(byDescending: "createdAt")
return q
}
}
Here are a few images of what the problem looks like:
Edit 1:
As suggested in the comments, I even tried to debug view hierarchy but I don't know which element to delete to make the grey bar go away.
It looks like it might be your navigation bar. Have you tried using this:
self.navigationController?.setNavigationBarHidden(true, animated: true)
instead of the statement you have of:
self.navigationController?.isNavigationBarHidden = true
Update #2:
Actually, I just realized you have that in the viewDidLoad. Move that to viewWillAppear and I bet it will work.
Update #3:
Just to reflect the true fix here, the offending code was in the viewDidAppear:
navigationController?.isNavigationBarHidden = false

UISearchController Filter Swift

I have a UITableViewCell with 3 subviews that I would like to filter when I search, as seen here:
1.The image view
2.The name label (black text)
3.The street name label (blue text)
This is what I've done so far, I've only managed to understand how to filter 1 array which is the name:
MainTableView.swift
var FilteredNames = [String]
func updateSearchResultsForSearchController(searchController:UISearchController) {
// Filter Names
self.filteredNames = self.names.filter { (name:String) -> Bool in
if name.lowercaseString.containsString(self.searchController.searchBar.text!.lowercaseString){
return true
} else {
return false
}
}
self.resultsController.tableView.reloadData()
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100.5
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Search
if tableView == self.tableView {
self.streets.count
return self.names.count
} else {
self.filteredStreets.count
return self.filteredNames.count
}
// return names.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell = self.tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as! CustomCell
if tableView == self.tableView {
cell.photo.image = self.images[indexPath.row]
cell.name.text = names[indexPath.row]
cell.streetName.text = streets[indexPath.row]
} else {
cell.photo.image = self.images[indexPath.row]
cell.name.text = self.filteredNames[indexPath.row]
cell.streetName.text = self.streets[indexPath.row]
}
return cell
}
As of right now, when I search, the image view & the street label are not synchronized with the name. I want to filter all 3 subviews to synchronize correctly. How can I achieve this?
I understand i need to use a struct and filter all 3 with one object but i'v encountered some difficulties managing to do that any help will be appreciated thank you !
Edit:here is my code right now:
override func viewDidLoad() {
super.viewDidLoad()
var searchController : UISearchController!
var resultsController = UITableViewController()
// //
definesPresentationContext = true
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 = true
self.searchController.searchBar.sizeToFit()
self.searchController.searchBar.barTintColor = UIColor.blackColor()
self.searchController.searchBar.endEditing(true)
self.searchController.searchBar.placeholder = "חפש ברים"
allUsers = createUsers(names: names, streets: streets, images: images)
filteredUsers = allUsers
}
var allUsers: [User]!
var filteredUsers: [User]!
func createUsers(names names: [String], streets: [String], images: [UIImage?]) -> [User] {
var users = [User]()
guard names.count == streets.count && names.count == images.count else { return users }
for (index, name) in names.enumerate() {
let user = User(name: name, streetName: streets[index], image: images[index])
users.append(user)
}
return users
}
//MARK : Search !
func updateSearchResultsForSearchController(searchController:UISearchController) {
if let searchText = searchController.searchBar.text?.lowercaseString {
if searchText.characters.count == 0 {
filteredUsers = allUsers
}
else {
filteredUsers = allUsers.filter {
return $0.name.lowercaseString.containsString(searchText) ||
$0.streetName.lowercaseString.containsString(searchText)
}
}
}
self.resultsController.tableView.reloadData()
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return 100.5;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
////////
////////
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredUsers.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell = self.tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as! CustomCell
let user = filteredUsers[indexPath.row]
cell.photo.image = user.image
cell.name.text = user.name
cell.streetName.text = user.streetName
return cell
}
I would strongly recommend to have only one dataSource instead of separate arrays for names, street names and images. In the following code filteredUsers is always used as dataSource and allUsers is just a stored full array, which is used for updating filteredUsers every time a new text is entered in search bar.
Create a model:
struct User {
var name: String
var streetName: String
var image: UIImage?
}
ViewController:
var allUsers: [User]!
var filteredUsers: [User]!
override func viewDidLoad() {
super.viewDidLoad()
//assuming you already have three arrays with the same amount of elements in each:
allUsers = createUsers(names: names, streets: streets, images: images)
filteredUsers = allUsers
}
func createUsers(names names: [String], streets: [String], images: [UIImage?]) -> [User] {
var users = [User]()
guard names.count == streets.count && names.count == images.count else { return users }
for (index, name) in names.enumerate() {
let user = User(name: name, streetName: streets[index], image: images[index])
users.append(user)
}
return users
}
func updateSearchResultsForSearchController(searchController:UISearchController) {
if let searchText = searchController.searchBar.text?.lowercaseString {
if searchText.characters.count == 0 {
filteredUsers = allUsers
}
else {
filteredUsers = allUsers.filter {
return $0.name.lowercaseString.containsString(searchText) ||
$0.streetName.lowercaseString.containsString(searchText)
} ?? []
}
}
self.resultsController.tableView.reloadData()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredUsers ? filteredUsers.count : 0
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell = self.tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as! CustomCell
let user = filteredUsers[indexPath.row]
cell.photo.image = user.image
cell.name.text = user.name
cell.streetName.text = user.streetName
return cell
}

found nil while trying to segue away from a tableView

I'm getting errors whenever I try to reference the viewTable in the viewDidLoad AFTER I click on a cell to transition with the segue. Thanks a lot!!
Basically I can't use the segue unless I comment out the tableview references in view did load... but I need those in order to use the search bar and im sure it will cause problems on the way back...
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView! {
didSet {
print("tableView is set")
}
}
let searchController = UISearchController(searchResultsController: nil)
let textCellIdentifier = "TextCell"
var buildings: [(String,String)] = []
var filteredBuildings = [(String,String)]()
var goToIndex: Int?
override func viewDidLoad() {
super.viewDidLoad()
print(tableView)
var buildingTuples = loadBuildings()
for tuple in buildingTuples {
self.buildings.append(tuple)
}
self.goToIndex = -1
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView!.tableHeaderView = searchController.searchBar
}
func filterContentForSearchText(searchText: String, scope: String = "All") {
filteredBuildings = buildings.filter { building in
return building.0.lowercaseString.containsString(searchText.lowercaseString)
}
self.tableView.reloadData()
}
// MARK: UITextFieldDelegate Methods
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return self.buildings.count
if searchController.active && searchController.searchBar.text != "" {
return filteredBuildings.count
}
return buildings.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
/*
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath)
let row = indexPath.row
cell.textLabel?.text = buildings[row].0
return cell
*/
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath)
let tuple: (String, String)
if searchController.active && searchController.searchBar.text != "" {
tuple = filteredBuildings[indexPath.row]
} else {
tuple = buildings[indexPath.row]
}
cell.textLabel?.text = tuple.0
return cell
}
// MARK: UITableViewDelegate Methods
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//tableView.deselectRowAtIndexPath(indexPath, animated: true)
let row = indexPath.row
self.goToIndex = indexPath.row
self.performSegueWithIdentifier("MainToLocation", sender: self)
//print(buildings[row].0)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "MainToLocation" {
let locationViewController = (segue.destinationViewController as! LocationViewController)
locationViewController.building = self.buildings[self.goToIndex!]
}
}
extension ViewController: UISearchResultsUpdating {
func updateSearchResultsForSearchController(searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
}
You can try this..
let destinationVC = self.storyboard!.instantiateViewControllerWithIdentifier("viewController") as! NextViewController
var alreadyPushed = false
if let vc = self.navigationController?.viewControllers {
for viewController in vc {
if let viewController = viewController as? NextViewController {
self.navigationController?.popToViewController(viewController, animated: true)
print("Push your controller")
alreadyPushed = true
break
}
}
}
if alreadyPushed == false {
self.navigationController?.pushViewController(destinationVC, animated: true)
}

Use of unresolved identifier 'scope' why this error will be come in following code

This is a program for searching a candies
but the Xcode will shows a unresolved scope identifier error
import UIKit
class SearchTableViewController: UITableViewController, UISearchBarDelegate, UISearchDisplayDelegate {
var searches = [Search]()
var filteredSearches = [Search]()
override func viewDidLoad() {
super.viewDidLoad()
self.searches = [Search(category:"Chocolate", name:"chocolate Bar"),
Search(category:"Chocolate", name:"chocolate Chip"),
Search(category:"Chocolate", name:"dark chocolate"),
Search(category:"Hard", name:"lollipop"),
Search(category:"Hard", name:"candy cane"),
Search(category:"Hard", name:"jaw breaker"),
Search(category:"Other", name:"caramel"),
Search(category:"Other", name:"sour chew"),
Search(category:"Other", name:"gummi bear")]
// Reload the table
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func filterContentForSearchText(searchText: String) {
// Filter the array using the filter method
self.filteredSearches = self.searches.filter({( search: Search) -> Bool in
let categoryMatch = (scope == "All") || (search.category == scope)
let stringMatch = search.name.rangeOfString(searchText)
return categoryMatch && (stringMatch != nil)
//return true
})
}
func searchDisplayController(controller:UISearchDisplayController, shouldReloadTableForSearchString searchString: String!) -> Bool {
self.filterContentForSearchText(searchString)
return true
}
func searchDisplayController(controller: UISearchDisplayController, shouldReloadTableForSearchScope searchOption: Int) -> Bool
{
self.filterContentForSearchText(self.searchDisplayController!.searchBar.text)
return true
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == self.searchDisplayController!.searchResultsTableView {
return self.filteredSearches.count
} else {
return self.searches.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell
var search : Search
// Check to see whether the normal table or search results table is being displayed and set the Candy object from the appropriate array
if tableView == self.searchDisplayController!.searchResultsTableView {
search = filteredSearches[indexPath.row]
} else {
search = searches[indexPath.row]
}
// Configure the cell
cell.textLabel!.text = search.name
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("searchDetail", sender: tableView)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "searchDetail"
{
let candyDetailViewController = segue.destinationViewController as! UIViewController
if sender as! UITableView == self.searchDisplayController!.searchResultsTableView
{
let indexPath = self.searchDisplayController!.searchResultsTableView.indexPathForSelectedRow()!
let destinationTitle = self.filteredSearches[indexPath.row].name
candyDetailViewController.title = destinationTitle
} else {
let indexPath = self.tableView.indexPathForSelectedRow()!
let destinationTitle = self.searches[indexPath.row].name
candyDetailViewController.title = destinationTitle
}
}
}
}
The method implementation is incorrect, this is the correct method:
func filterContentForSearchText(searchText: String, scope: String = "All") {
self.filteredCandies = self.candies.filter({( candy : Candy) -> Bool in
var categoryMatch = (scope == "All") || (candy.category == scope)
var stringMatch = candy.name.rangeOfString(searchText)
return categoryMatch && (stringMatch != nil)
})
}
You forgot to declare the variable 'scope' in the method ;)

Resources