UISearchBar:传递数据;单击的标题与 ListViewController 中显示的数据不对应 - Swift
UISearchBar: passing data; Title that is clicked on does not correspond with data that is shown in ListViewController - Swift
我目前的 UISearchBar 有问题。因此,当我搜索一个词时,UISearchBar returns 匹配我输入的字母/词的数据。但是,当我单击其中一个表格视图单元格时,(标题)数据与 ListViewController 中显示的(项目)数据不对应。它显示的是(在 ListViewController 中)与 tableView 的原始 order/layout(索引)相对应的(项目)数据。因此,在搜索后,如果我单击与我搜索的内容匹配的第一个 tableView 单元格的 (title),它会显示 (titledata) 数组中第一个 (string) 的 (items) 数据,而不是对应于标题显示。
例如:
如果我在我的 SearchBar New Haven(索引 1)和 New York(索引 2)中键入“New”弹出。但是,当我单击(标题)New Haven tableView 单元格时,它会将我带到 Ann Arbor 的(项目)数据(原始布局的第一个索引)
谢谢!
结构代码:
struct Category {
let title: String
let items: [String]
}
数据(数组:从结构派生)代码:
let data: [Category] = [
Category(title: "Ann Arbor", items: ["Ann Arbor is a city located in Michigan.", "Population: 119,000","University: University of Michigan is located in Ann Arbor.",]),
Category(title: "Los Angeles", items: ["Los Angeles is a city located in California.", "Population: 3,900,000,", "University: University of California of Los Angeles",]),
Category(title: "New Haven", items: ["New Haven is a city located in Connecticut.", "Population: 130,000 ","University: Yale University",]),
Category(title: "New York City", items: ["New York City is located in New York.", "Population: 8,300,000","University: Columbia University",]),
Category(title: "San Fransisco", items: ["Ann Arbor is a city located in Michigan.", "Population: 881,000","University: University of San Francisco",]),
]
titledata(数组)代码:
let titledata = ["Ann Arbor", "Los Angeles","New Haven", "New York City", "San Fransisco"]
过滤数据变量:
var filteredData: [String]!
在 viewDidLoad 函数中:
filteredData = titledata
注意:在 Storyboard 中链接了 SearchBar Delegate。
UISearchBar 代码:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredData = []
if searchText == "" {
filteredData = titledata
}
else {
for info in titledata {
if info.lowercased().contains(searchText.lowercased()) {
self.tableView.reloadData()
filteredData.append(info)
self.tableView.reloadData()
}
}
}
self.tableView.reloadData()
}
didSelectRowAt 函数:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let category = data[indexPath.row]
let vc = ListViewController(items: category.items)
vc.title = category.title
self.navigationController?.pushViewController(vc, animated: true)
}
numberOfRowsInSection 函数:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
cellForRowAt 函数:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
cell.myLabel.text = filteredData[indexPath.row]
cell.myImg.image = UIImage(named: filteredData[indexPath.row] + ".png")
return cell
}
问题出在您的方法 didSelectRowAt
中,您正在使用 filteredData
数组来显示项目,但是当您在单元格上执行点击时,您使用的是不同的数组:
let category = data[indexPath.row]
当您在单元格上执行点击时,您也需要使用过滤数组:
let category = filteredData[indexPath.row]
首先声明一个数据源数组总是non-optional空数组。
编辑:您的数据源应该是[Category]
而不是[String]
var filteredData = [Category]()
在viewDidLoad
赋值data
中,不需要titledata
数组。删除它。
filteredData = data
由于 filteredData
是数据源数组,您必须从 didSelectRowAt
中的此数组中获取项目
let category = filteredData[indexPath.row]
还有一些可以优化的东西。
在 textDidChange
中,过滤数据的方式非常昂贵,因为存在循环,而且更糟糕的是,在每次迭代中都会重新加载 table 视图。
这样效率更高
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.isEmpty {
filteredData = data
} else {
filteredData = data.filter{[=13=].title.range(of: searchText, options: .caseInsensitive) != nil }
}
self.tableView.reloadData()
}
并将cellForRowAt
替换为
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
let title = filteredData[indexPath.row].title
cell.myLabel.text = title
cell.myImg.image = UIImage(named: title + ".png")
return cell
}
如果您喜欢漂亮的动画,请使用 UITableViewDiffableDataSource
,它会在数据源数组更改时为 table 视图设置动画
我目前的 UISearchBar 有问题。因此,当我搜索一个词时,UISearchBar returns 匹配我输入的字母/词的数据。但是,当我单击其中一个表格视图单元格时,(标题)数据与 ListViewController 中显示的(项目)数据不对应。它显示的是(在 ListViewController 中)与 tableView 的原始 order/layout(索引)相对应的(项目)数据。因此,在搜索后,如果我单击与我搜索的内容匹配的第一个 tableView 单元格的 (title),它会显示 (titledata) 数组中第一个 (string) 的 (items) 数据,而不是对应于标题显示。
例如: 如果我在我的 SearchBar New Haven(索引 1)和 New York(索引 2)中键入“New”弹出。但是,当我单击(标题)New Haven tableView 单元格时,它会将我带到 Ann Arbor 的(项目)数据(原始布局的第一个索引)
谢谢!
结构代码:
struct Category {
let title: String
let items: [String]
}
数据(数组:从结构派生)代码:
let data: [Category] = [
Category(title: "Ann Arbor", items: ["Ann Arbor is a city located in Michigan.", "Population: 119,000","University: University of Michigan is located in Ann Arbor.",]),
Category(title: "Los Angeles", items: ["Los Angeles is a city located in California.", "Population: 3,900,000,", "University: University of California of Los Angeles",]),
Category(title: "New Haven", items: ["New Haven is a city located in Connecticut.", "Population: 130,000 ","University: Yale University",]),
Category(title: "New York City", items: ["New York City is located in New York.", "Population: 8,300,000","University: Columbia University",]),
Category(title: "San Fransisco", items: ["Ann Arbor is a city located in Michigan.", "Population: 881,000","University: University of San Francisco",]),
]
titledata(数组)代码:
let titledata = ["Ann Arbor", "Los Angeles","New Haven", "New York City", "San Fransisco"]
过滤数据变量:
var filteredData: [String]!
在 viewDidLoad 函数中:
filteredData = titledata
注意:在 Storyboard 中链接了 SearchBar Delegate。
UISearchBar 代码:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredData = []
if searchText == "" {
filteredData = titledata
}
else {
for info in titledata {
if info.lowercased().contains(searchText.lowercased()) {
self.tableView.reloadData()
filteredData.append(info)
self.tableView.reloadData()
}
}
}
self.tableView.reloadData()
}
didSelectRowAt 函数:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let category = data[indexPath.row]
let vc = ListViewController(items: category.items)
vc.title = category.title
self.navigationController?.pushViewController(vc, animated: true)
}
numberOfRowsInSection 函数:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
cellForRowAt 函数:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
cell.myLabel.text = filteredData[indexPath.row]
cell.myImg.image = UIImage(named: filteredData[indexPath.row] + ".png")
return cell
}
问题出在您的方法 didSelectRowAt
中,您正在使用 filteredData
数组来显示项目,但是当您在单元格上执行点击时,您使用的是不同的数组:
let category = data[indexPath.row]
当您在单元格上执行点击时,您也需要使用过滤数组:
let category = filteredData[indexPath.row]
首先声明一个数据源数组总是non-optional空数组。
编辑:您的数据源应该是[Category]
而不是[String]
var filteredData = [Category]()
在viewDidLoad
赋值data
中,不需要titledata
数组。删除它。
filteredData = data
由于 filteredData
是数据源数组,您必须从 didSelectRowAt
let category = filteredData[indexPath.row]
还有一些可以优化的东西。
在 textDidChange
中,过滤数据的方式非常昂贵,因为存在循环,而且更糟糕的是,在每次迭代中都会重新加载 table 视图。
这样效率更高
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.isEmpty {
filteredData = data
} else {
filteredData = data.filter{[=13=].title.range(of: searchText, options: .caseInsensitive) != nil }
}
self.tableView.reloadData()
}
并将cellForRowAt
替换为
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
let title = filteredData[indexPath.row].title
cell.myLabel.text = title
cell.myImg.image = UIImage(named: title + ".png")
return cell
}
如果您喜欢漂亮的动画,请使用 UITableViewDiffableDataSource
,它会在数据源数组更改时为 table 视图设置动画