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