数组索引超出搜索范围

时间:2015-12-23 13:23:17

标签: arrays swift search

我试图在我的应用中实现“搜索”,效果很好,但是如果点击搜索栏,则不输入任何内容,然后点击清除按钮或点击搜索结果和“返回”按钮,然后“数组索引超出范围错误出现。

import UIKit

class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate {

@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var tableView: UITableView!
var filteredCats = [Cats]()
var searchActive : Bool = false

func loadList(notification: NSNotification){
    //load data here
    self.tableView.reloadData()
}
func dismissKeyboard() {
    //Causes the view (or one of its embedded text fields) to resign the first responder status.
    view.endEditing(true)
}



override func viewDidLoad() {
    super.viewDidLoad()
     NSNotificationCenter.defaultCenter().addObserver(self, selector: "loadList:",name:"load", object: nil)


    // Установка параметров поиска
    searchBar.tintColor = UIColor.whiteColor()
    let textFieldInsideSearchBar = searchBar.valueForKey("searchField") as? UITextField
    textFieldInsideSearchBar?.textColor = UIColor.whiteColor()

    //Настраиваем отображение ячеек таблицей
    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 215.0
    tableView.separatorStyle = .None


    print(filteredCats.count, searchActive)
    // 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
    dismissKeyboard()

}

func searchBarSearchButtonClicked(searchBar: UISearchBar) {
    searchActive = false;
    dismissKeyboard()

}

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

    filteredCats = catsArray.filter({ (Cats) -> Bool in
        let tmp: NSString = Cats.title
        let range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
        return range.location != NSNotFound
    })
    if(filteredCats.count == 0){
        searchActive = false;
    } else {
        searchActive = true;
    }
    self.tableView.reloadData()
    }

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    //Считаем количество котов
    if(searchActive) {
        return self.filteredCats.count
    } else {
        return catsArray.count
    }
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("catCell") as! TableViewCell

    var catTitle = String()
    var catImage = String()

    if(searchActive){
        catTitle = filteredCats[indexPath.row].title
        catImage = filteredCats [indexPath.row].icon
    } else {
        catTitle = catsArray[indexPath.row].title
        catImage = catsArray[indexPath.row].icon
    }




    if favorite.contains(catsArray[indexPath.row].index) {
        cell.setCell(catTitle, imageName: "\(catImage)-1", buttonImage: containsInFavorite!)
        cell.selectionStyle = UITableViewCellSelectionStyle.None
        } else {
            cell.setCell(catTitle, imageName: "\(catImage)-1", buttonImage: dontContainsInFavorite!)
        }

    cell.favoriteButton.tag = indexPath.row
    cell.favoriteButton.addTarget(self, action: "switchFavorite:", forControlEvents: .TouchUpInside)

    return cell

    }

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "showDetail" {
        print("showDetail seque called")
        let detailView = segue.destinationViewController as! DetailViewController
        detailView.hidesBottomBarWhenPushed = true

        let backItem = UIBarButtonItem()
        backItem.title = "Back"
        navigationItem.backBarButtonItem = backItem

        if filteredCats.count != 0 {
            if let catIndex = tableView.indexPathForSelectedRow?.row {
                let finalIndex = filteredCats[catIndex].index
                detailView.catInfoIndex = finalIndex
                print(catIndex, filteredCats.count)
            }
        } else {
        if let catIndex = tableView.indexPathForSelectedRow?.row {
            detailView.catInfoIndex = catIndex
            print(catIndex, filteredCats.count)
        }
        }   
    }
}
override func viewWillAppear(animated: Bool) {
    print(filteredCats.count, searchActive)
} 
}

1 个答案:

答案 0 :(得分:2)

感谢您的帮助。 我解决了这个问题。 当我完成编辑“searchActive”时,就会发生这种情况。 var变为“假”,如果在此之后我点击“清除”' SearchBar中UITesxtField中的按钮,然后是tableView.reload()调用,只有在此之后' searchActive变为“真实”,这就是为什么&f; func tableView numberOfRowsInSection'和&f; func tableView cellForRowAtIndexPath'工作不合适,并且在数组范围内做出索引'出现错误。

通过添加一个' if ... else'来解决它。在这种方法中:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    //Считаем количество котов в библиотеке
    if(searchActive) {
        if filteredCats.count == 0{
            return catsArray.count
        } else {
        return self.filteredCats.count
        }
    } else {
        return catsArray.count
        }

}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("catCell") as! TableViewCell



    //Устанавливаем параметры ячеек
    cell.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0)
    cell.selectionStyle = UITableViewCellSelectionStyle.None

    var catTitle = String()
    var catImage = String()

    if(searchActive){
        if filteredCats.count == 0{
            catTitle = catsArray[indexPath.row].title
            catImage = catsArray[indexPath.row].icon
        } else {
            catTitle = filteredCats[indexPath.row].title
            catImage = filteredCats [indexPath.row].icon

        }
    } else {
        catTitle = catsArray[indexPath.row].title
        catImage = catsArray[indexPath.row].icon
    }