我一直试图在这个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
,然后检索到实际结果。
然而,搜索本身仍无效,但大多数问题已得到解决。点击搜索栏时,它只检索数组的最终索引,并在搜索任何内容时删除该值。我将继续努力,希望尽快解决问题。感谢您的帮助!
答案 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] %@
,现在搜索时,它会显示正确的匹配对象就其名字而言。