在结构上使用 UISearchbar
Using UISearchbar on Struct
我的项目中有两个 UITableViewControllers
。第一个只是一个简单的 tableView
,它显示一个普通的 array
。第二个 tableView
由 Struct
填充
我已经在第一个 ViewController
中实现了 UISearcBar
,没有任何问题。我遵循 this guide 这是我在第一个 viewController
中用于搜索栏的代码:
let listArray = ["Item1", "Item2", "Item3", "Item4", "Item5"]
var searchData: [String]!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
searchBar.delegate = self
searchData = listArray
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as UITableViewCell
cell.textLabel?.text = searchData[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchData = searchText.isEmpty ? listArray : listArray { (item: String) -> Bool in
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
tableView.reloadData()
}
在第二个 ViewController
中,我使用 Struct
来填充 tableView
当我尝试实现 searchBar 时出现错误:
struct ObjectModel {
var objectProducer: String?
var objecType: String?
var unit: String?
var contentSize: Double?
var amount: Double?
var addedDate: String?
}
var objectList = [ObjectModel]()
//Search data
var filteredData = [ObjectModel]()
override func viewDidLoad() {
super.viewDidLoad()
//SearchData
searchBar.delegate = self
filteredData = objectList //
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell") as! ListCell
//the artist object
let object: ObjectModel
object = objectList[indexPath.row]
if activeSearch = false {
cell.objectNameLabel.text = "\(object.objectProducer ?? "Missing data"), \(object.objecType ?? "Missing data")"
} else {
cell.objectNameLabel.text = filteredData[indexPath.row] //Error: Cannot assign value of type 'ObjectModel' to type 'String?'
}
return cell
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredData = searchText.isEmpty ? objectList : objectList.filter { (item: String) -> Bool in //Error: 'String' is not convertible to 'ObjectModel'
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
tableView.reloadData()
}
使用Struct
时应该如何实现搜索?
你必须改变
cell.objectNameLabel.text = filteredData[indexPath.row]
到
cell.objectNameLabel.text = filteredData[indexPath.row].objectProducer
因为在 ObjectModel
结构中,您必须分配 属性 之一必须分配给 UILabel
的 text
变量。您可以分配
var objectProducer: String?
var objecType: String?
var unit: String?
var contentSize: Double?
var amount: Double?
var addedDate: String?
属性String
描述。例如,如果你想分配金额,你可以使用
cell.objectNameLabel.text = "\(filteredData[indexPath.row].amount!)"
或者有更好的方法。
你必须用 CustomStringConvertible
扩展你的 ObjectModel
这样你的所有结构变量都可以描述为字符串然后它可以像那样工作
cell.objectNameLabel.text = filteredData[indexPath.row]
你可以像下面这样扩展它。
extension ObjectModel: CustomStringConvertible{
public var description: String {
return "amount \(self.amount) producer \(self.producer) bla bla"
}
}
// 编辑
用主线程改成它。
tableView.reloadData()
至:
DispatchQueue.main.async {
self.tableView.reloadData()
}
我的项目中有两个 UITableViewControllers
。第一个只是一个简单的 tableView
,它显示一个普通的 array
。第二个 tableView
由 Struct
填充
我已经在第一个 ViewController
中实现了 UISearcBar
,没有任何问题。我遵循 this guide 这是我在第一个 viewController
中用于搜索栏的代码:
let listArray = ["Item1", "Item2", "Item3", "Item4", "Item5"]
var searchData: [String]!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
searchBar.delegate = self
searchData = listArray
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as UITableViewCell
cell.textLabel?.text = searchData[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchData = searchText.isEmpty ? listArray : listArray { (item: String) -> Bool in
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
tableView.reloadData()
}
在第二个 ViewController
中,我使用 Struct
来填充 tableView
当我尝试实现 searchBar 时出现错误:
struct ObjectModel {
var objectProducer: String?
var objecType: String?
var unit: String?
var contentSize: Double?
var amount: Double?
var addedDate: String?
}
var objectList = [ObjectModel]()
//Search data
var filteredData = [ObjectModel]()
override func viewDidLoad() {
super.viewDidLoad()
//SearchData
searchBar.delegate = self
filteredData = objectList //
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell") as! ListCell
//the artist object
let object: ObjectModel
object = objectList[indexPath.row]
if activeSearch = false {
cell.objectNameLabel.text = "\(object.objectProducer ?? "Missing data"), \(object.objecType ?? "Missing data")"
} else {
cell.objectNameLabel.text = filteredData[indexPath.row] //Error: Cannot assign value of type 'ObjectModel' to type 'String?'
}
return cell
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredData = searchText.isEmpty ? objectList : objectList.filter { (item: String) -> Bool in //Error: 'String' is not convertible to 'ObjectModel'
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
tableView.reloadData()
}
使用Struct
时应该如何实现搜索?
你必须改变
cell.objectNameLabel.text = filteredData[indexPath.row]
到
cell.objectNameLabel.text = filteredData[indexPath.row].objectProducer
因为在 ObjectModel
结构中,您必须分配 属性 之一必须分配给 UILabel
的 text
变量。您可以分配
var objectProducer: String?
var objecType: String?
var unit: String?
var contentSize: Double?
var amount: Double?
var addedDate: String?
属性String
描述。例如,如果你想分配金额,你可以使用
cell.objectNameLabel.text = "\(filteredData[indexPath.row].amount!)"
或者有更好的方法。
你必须用 CustomStringConvertible
扩展你的 ObjectModel
这样你的所有结构变量都可以描述为字符串然后它可以像那样工作
cell.objectNameLabel.text = filteredData[indexPath.row]
你可以像下面这样扩展它。
extension ObjectModel: CustomStringConvertible{
public var description: String {
return "amount \(self.amount) producer \(self.producer) bla bla"
}
}
// 编辑
用主线程改成它。
tableView.reloadData()
至:
DispatchQueue.main.async {
self.tableView.reloadData()
}