UISearchBar 搜索功能不起作用
UISearchBar search function does not work
我已经尝试在此 iOS 应用程序上实现搜索功能已有一段时间了。
我有一个包含所有数据的 JSON 文件,然后将其拉取并显示到 table 视图控制器上。
我已经实现了搜索栏并遵循了几个教程,这个问题最少 - http://www.ioscreator.com/tutorials/add-search-table-view-tutorial-ios8-swift (I've also used this too previously - 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
}
然后使用以下
将其调用到table视图控制器中
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 进行搜索时,在我单击它的那一刻,我得到了 "fatal error: array cannot be bridged from Objective-C"。我相信这是因为教程中使用的数组与我使用的数组类型不同。
更新
首先,主要问题是我使用的数组类型与教程不同;所以我将 var filteredAnimal = [String]()
更改为 var filteredArray = [[String:AnyObject]]()
,因为数据 source/JSON 文件包含大量数据数组。并因此将其视为 AnyObject,这样我就可以从 JSON 文件中调用特定信息。
返回空数组的原因是因为我没有在 updateSearchResultsController
方法中分配空数组中的搜索值,所以我在重新加载 [=74] 之前添加了以下内容=]数据-filteredArray = arrays as [[String:AnyObject]]
这仍然没有解决问题,因为我不得不将 numberOfRowsInSection
中的 if 语句从 tableView == self.searchDisplayController?.searchResultsTableView
更改为 self.resultSearchController.active
,然后检索到一个实际结果。
然而,搜索本身仍然无法正常工作,但大多数问题已得到解决。点击搜索栏时,它只会检索数组的最终索引,而在搜索任何内容时,它会删除该值。我会继续努力,希望尽快解决这个问题。感谢到目前为止的帮助!
以下link可能会帮助您解决问题:
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.
自上次更新(对解决方案起到了重要作用)以来,我所做的只是将 NSPredicate 查询从 SELF CONTAINS[c] %@
更改为 name CONTAINS[c] %@
,现在在搜索时,它显示正确的匹配基于名称的对象。
我已经尝试在此 iOS 应用程序上实现搜索功能已有一段时间了。
我有一个包含所有数据的 JSON 文件,然后将其拉取并显示到 table 视图控制器上。
我已经实现了搜索栏并遵循了几个教程,这个问题最少 - http://www.ioscreator.com/tutorials/add-search-table-view-tutorial-ios8-swift (I've also used this too previously - 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
}
然后使用以下
将其调用到table视图控制器中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 进行搜索时,在我单击它的那一刻,我得到了 "fatal error: array cannot be bridged from Objective-C"。我相信这是因为教程中使用的数组与我使用的数组类型不同。
更新
首先,主要问题是我使用的数组类型与教程不同;所以我将 var filteredAnimal = [String]()
更改为 var filteredArray = [[String:AnyObject]]()
,因为数据 source/JSON 文件包含大量数据数组。并因此将其视为 AnyObject,这样我就可以从 JSON 文件中调用特定信息。
返回空数组的原因是因为我没有在 updateSearchResultsController
方法中分配空数组中的搜索值,所以我在重新加载 [=74] 之前添加了以下内容=]数据-filteredArray = arrays as [[String:AnyObject]]
这仍然没有解决问题,因为我不得不将 numberOfRowsInSection
中的 if 语句从 tableView == self.searchDisplayController?.searchResultsTableView
更改为 self.resultSearchController.active
,然后检索到一个实际结果。
然而,搜索本身仍然无法正常工作,但大多数问题已得到解决。点击搜索栏时,它只会检索数组的最终索引,而在搜索任何内容时,它会删除该值。我会继续努力,希望尽快解决这个问题。感谢到目前为止的帮助!
以下link可能会帮助您解决问题:
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.
自上次更新(对解决方案起到了重要作用)以来,我所做的只是将 NSPredicate 查询从 SELF CONTAINS[c] %@
更改为 name CONTAINS[c] %@
,现在在搜索时,它显示正确的匹配基于名称的对象。