如何使用 NSMutableArray 和 UISearchController 进行过滤

How Can I Filtering Using NSMutableArray and UISearchController

我正在使用 Swift 开发一个 iOS 应用程序,我正在使用 NSMutableArray,当我尝试将 UISearchController 添加到我的 UITableViewController 时,它给我这个错误

1.1 click here, please

但是当我尝试使用 NSArray 时,效果很好。

如果你想知道我为什么要使用 NSMutableArray? 因为我需要它将选定行中的 NSMutableArray 对象从 UITableViewController 传递到另一个 UIViewController,如下所示: 1.2 click here, please

我现在要做的是,如何添加搜索栏? 提前致谢。

您可以通过将可变数组转换为 nsarray 然后使用它来破解它。

你在 1.1 中做的事情只是在 self.businessNamesArray 行之前添加这一行

var regArray = self.businessNamesArray as NSArray as! [字符串]

然后将 self.businessNamesArray 行更改为 regArray.filter{ 其余代码在此处

如果您使用常规 Swift 数组,我认为这是正确的想法,因为您使用的是 Swift,如果您更改数组变量类型并修复数组,则可以使其正常工作过滤语法。首先,将数组声明更改为:

var BusinessNamesArray:[String]?

您在 self.BusinessNamesArray returns 过滤数组上使用的 filter 函数,而不是就地过滤数组(这似乎是您想要的)。如果你想替换你的 self.BusinessNamesArray 的内容,你需要做这样的事情:

func updateSearchResultsForSearchController(searchController: UISearchController) {
    self.BusinessNamesArray = self.BusinessNamesArray.filter { (business:String) -> Bool in 
        return true
        // You probably want to compare strings here like this instead:
        // guard let searchText = searchController.searchBar.text else {
        //     return false
        // }
        // return business.hasPrefix(searchText)
    }
    // You probably also need to reload your table view at this point:
    self.tableView.reloadData()
}

请记住,您的 BusinessNamesArray 现在已被过滤,您无法取消过滤。相反,您应该保留第二个字符串数组,名称类似于 searchResults。然后您可以使用它来过滤和维护原始数组中的原始企业名称列表。因此,您将添加一个名为 var searchResults:[String]? 的 class 变量,搜索过滤代码将更改为。

func updateSearchResultsForSearchController(searchController: UISearchController) {
    self.searchResults = self.BusinessNamesArray.filter { (business:String) -> Bool in 
        guard let searchText = searchController.searchBar.text else {
            return false
        }
        return business.hasPrefix(searchText)
    }
    self.tableView.reloadData()
}

此时当您在 table 视图上调用 reloadData 时,您可能想要检查并查看您的搜索控制器是否在 table 视图委托的 numberOfSectionsInTableView 以及其他委托函数,如果它处于活动状态则使用 searchResults 数组,如果它不处于活动状态则使用 BusinessNamesArray——类似于:

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    if (self.resultSearchController.active) {
        return self.searchResults.count ?? 0
    } else {
        return self.BusinessNamesArray.count ?? 0
    }
}

self.resultSearchController 变量是 UISearchController 的本地实例。我不确定你给你的变量命名的是什么。)

然后您将使用类似的代码来决定要为您的 prepareForSegue: 代码获取哪些项目:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // Guard your variables here so you can return early if they're 
    // not valid
    guard let upcoming = segue.destinationViewController as? DetailsViewController, 
              myindexpath = self.tableView.indexPathForSelectedRow else {
        return
    }

    var titleString = ""
    if (self.resultSearchController.active) {
        if let searchResults = self.searchResults {
            titleString = searchResults[myindexpath.row]
        }
    } else {
        if let businessNames = self.BusinessNamesArray {
            titleString = businessNames[myindexpath.row]
        }
    }
    upcoming.titleString = titleString

    self.deselectRowAtIndexPath(myindexpath, animated: true)
}