UISearchBar搜索功能不起作用

时间:2015-09-16 13:58:22

标签: ios iphone swift uitableview uisearchbar

我一直试图在这个iOS应用上实现搜索功能已经有一段时间了。

我有一个包含所有数据的JSON文件,然后将其拉出并显示在表视图控制器上。

我已经实施了搜索栏并按照了几个教程,这个问题的问题最少 - http://www.ioscreator.com/tutorials/add-search-table-view-tutorial-ios8-swift(我之前也使用过这个问题 - https://www.youtube.com/watch?v=N9wcKc37ZXI

我的JSON文件结构如下:

{ "animal":[

    {
        "no":"001",
        "type":"dog",
        "breed":"pitbull",
        "classification":"mammal",
        "sprite":"beast"
    },
    {
        "no":"002",
        "type":"dog",
        "breed":"bulldog",
        "classification":"mammal",
        "sprite":"beast"
     },
    {
        "no":"003",
        "type":"cat",
        "breed":"birman",
        "classification":"mammal",
        "sprite":"feline"
     }

]}

我使用在单独文件中创建的结构来调用JSON数据

Animal.swift

struct animalStruct {
    static let path = NSBundle.mainBundle().pathForResource("animal", ofType: "JSON")

    static let jsonData = NSData(contentsOfFile:path!, options: .DataReadingMappedIfSafe, error: nil)

    static var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonData!, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
}

使用以下

将其调用到表视图控制器中

AnimalTableViewController

var array : NSArray = Animal.animalStruct.jsonResult["animal"] as NSArray

用于搜索的代码:

AnimalTableViewController

    @IBOutlet var segmentedSortOption: UISegmentedControl!
    var array : NSArray = Animal.pokemonStruct.jsonResult["animal"] as NSArray
    var filteredAnimal = [String]()
    var resultSearchController = UISearchController()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.resultSearchController = ({
            let controller = UISearchController(searchResultsController: nil)
            controller.searchResultsUpdater = self
            controller.dimsBackgroundDuringPresentation = false
            controller.searchBar.sizeToFit()

            self.tableView.tableHeaderView = controller.searchBar

            return controller
        })()
        self.tableView.reloadData()
    }

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

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if tableView == self.searchDisplayController?.searchResultsTableView {
        return self.filteredAnimal.count
        } else {
            return self.array.count
        }
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        var myCell:cell = self.tableView.dequeueReusableCellWithIdentifier("cell") as cell
        var upperCasedNames = array[indexPath.row]["name"] as? String
        var searchedItem:String

        if segmentedSortOption.selectedSegmentIndex == 0 {
            if (self.resultSearchController.active) {
                //**ISSUE OCCURS HERE**
                myCell.name.text = filteredAnimal[indexPath.row]
                return myCell
            }
            else {
                myCell.name.text = upperCasedNames?.uppercaseString
                return myCell
            }
        } else if segmentedSortOption.selectedSegmentIndex == 1 {

            if let unsortedEvents = Animal.animalStruct.jsonResult["animal"] as? NSArray {
                let descriptor = NSSortDescriptor(key: "name", ascending: true, selector: "caseInsensitiveCompare:")
                let aToZ = unsortedEvents.sortedArrayUsingDescriptors([descriptor])
                upperCasedNames = aToZ[indexPath.row]["name"] as? String
                myCell.name.text = upperCasedNames?.uppercaseString
            }
        }
        return myCell
    }

    func updateSearchResultsForSearchController(searchController: UISearchController)
    {
        filteredAnimal.removeAll(keepCapacity: false)
        let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text)
        let arrays = (array).filteredArrayUsingPredicate(searchPredicate!)
        filteredArray = arrays as [[String]]
        self.tableView.reloadData()
    }
}

我的问题

我遇到的问题是,当我尝试通过UISearchBar进行搜索时,我点击它的那一刻,我得到了#34;致命错误:数组无法与Objective-C"桥接。我相信这种情况正在发生,因为与我使用的数组相比,本教程中使用的数组是不同的类型。

更新

首先,主要问题是,与教程相比,我有一个不同类型的数组;所以我将var filteredAnimal = [String]()更改为var filteredArray = [[String:AnyObject]](),因为数据源/ JSON文件包含大量数据。并将其视为AnyObject,因此允许我从JSON文件中调用特定信息。

我返回一个空数组的原因是因为我没有在updateSearchResultsController方法中的空数组中分配搜索值,所以我在重新加载表数据之前添加了以下内容 - {{ 1}}

这仍然无法解决问题,因为我必须将filteredArray = arrays as [[String:AnyObject]]中的if语句从numberOfRowsInSection更改为tableView == self.searchDisplayController?.searchResultsTableView,然后检索到实际结果。

然而,搜索本身仍无效,但大多数问题已得到解决。点击搜索栏时,它只检索数组的最终索引,并在搜索任何内容时删除该值。我将继续努力,希望尽快解决问题。感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

以下链接可以帮助您解决问题:

How can I fix "fatal error: can't index empty buffer"

in your code

 let arrays = (array).filteredArrayUsingPredicate(searchPredicate!)

will create new reference of arrays.

答案 1 :(得分:0)

自从上次更新(已经成为解决方案的主要部分)以来,我所做的就是将NSPredicate查询从SELF CONTAINS[c] %@更改为name CONTAINS[c] %@,现在搜索时,它会显示正确的匹配对象就其名字而言。