无法使用 struct Array 实现 Swift/iOS searchBar
Trouble implementing Swift/iOS searchBar with struct Array
我有一个结构数组用于填充我的表视图。但是我无法让我的 searchBar 正常工作。我最初的 searchBar 代码是在我使用 more "basic" 数组时创建的。转换为结构后,它不再有效。我从 Xcode 收到 3 个错误。我用 // <-- ERROR 识别了代码中的错误。感谢您的帮助!
import UIKit
struct Material {
var name : String
var lbft : String
var gcm : String
}
class ViewController: UIViewController {
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet var tableView: UITableView!
let materialData = [
Material(name: "Acetaminohen Powder, Unmilled", lbft: "43", gcm: "0.688794"),
Material(name: "Acetylene Black, 100% Compressed", lbft: "35", gcm: "0.560646"),
Material(name: "Acetylsalicyic Acid", lbft: "20", gcm: "0.320369"),
Material(name: "Acrylamide", lbft: "34", gcm: "0.54463"),
Material(name: "Acrylic Granules, Coarse", lbft: "40", gcm: "0.64"),
Material(name: "Acrylic Granules, Fine", lbft: "36", gcm: "0.58"),
Material(name: "Acrylonitrile Butadien Styrene (Abs) Resin", lbft: "50", gcm: "0.8"),
Material(name: "Acrylonitrile Butadiene Styrene (Abs) Granules", lbft: "36", gcm: "0.58"),
Material(name: "Activated Alumina", lbft: "42.5", gcm: "0.68"),
Material(name: "Activated Carbon", lbft: "32.5", gcm: "0.52"),
Material(name: "Actylene Black", lbft: "45.5", gcm: "0.73"),
Material(name: "Aero Xanthates", lbft: "112.5", gcm: "1.8"),
Material(name: "Aerolyte", lbft: "51", gcm: "0.82"),
Material(name: "Aerosil, Fumed Silica", lbft: "32", gcm: "0.51"),
Material(name: "Aerosil, Silicon Dioxide", lbft: "30", gcm: "0.48"),
Material(name: "Alaluren", lbft: "112", gcm: "1.79")]
var searchMaterial = [String]()
var searching = false
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching {
return searchMaterial.count
} else {
return materialData.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.numberOfLines = 0
if searching {
cell.textLabel?.text = searchMaterial[indexPath.row]
} else {
cell.textLabel?.text = materialData[indexPath.row] // <-- ERROR Cannot assign value of type 'Material' to type 'String'
}
return cell
}
}
extension ViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchBar.setShowsCancelButton(true, animated: true)
searchMaterial = materialData.filter({[=11=].prefix(searchText.count) == searchText}) // <-- ERROR Cannot assign value of type '[Material]' to type '[String]'
// <-- ERROR Value of type 'Material' has no member 'prefix'
searching = true
tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.setShowsCancelButton(false, animated: true)
searching = false
searchBar.text = ""
tableView.reloadData()
}
}
没有
materialData[0] etc...
声明你的数组,例如
var searchMaterial:[String] = []
然后你可以像
一样访问它
searchMaterial[indexPath.row]
1) cell.textLabel?.text = materialData[indexPath.row]
materialData[indexPath.row] 将为您提供类型为 Material 而不是字符串的对象。不确定您期望的价值是多少。但将其更改为
materialData[indexPath.row].name
2) searchMaterial = materialData.filter({$0.prefix(searchText.count) == searchText}) // <-- 错误无法分配类型的值'[Material]' 键入 '[String]'
改为
var searchMaterial:[Material] = []
searchMaterial = materialData.filter { [=11=].name.contains(searchText) }
您要按 name
搜索吗?如果是这样,您可以像这样修复第二个 ERROR
:
searchMaterial = materialData
.map({ [=10=].name }) // convert to [String]
.filter { [=10=].hasPrefix(searchText) } // search
第一个可以这样修复:
cell.textLabel?.text = materialData[indexPath.row].name
嗨,肖恩,我相信我已经解决了这个问题,
您的 tableView 委托函数中的所有内容都是正确的
确保在顶层创建这个变量
var searchMaterial = [Material]()
然后将其添加到您的 searchBar 函数中:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
guard !searchText.isEmpty else {
searchMaterial = materialData
tableView.reloadData()
return // When no items are typed, load your array still
}
searchMaterial = materialData.filter({ (Material) -> Bool in
Material.title.lowercased().contains(searchText.lowercased())
})
searchBar.setShowsCancelButton(true, animated: true)
searching = true
tableView.reloadData()
希望对您有所帮助!!!
我有一个结构数组用于填充我的表视图。但是我无法让我的 searchBar 正常工作。我最初的 searchBar 代码是在我使用 more "basic" 数组时创建的。转换为结构后,它不再有效。我从 Xcode 收到 3 个错误。我用 // <-- ERROR 识别了代码中的错误。感谢您的帮助!
import UIKit
struct Material {
var name : String
var lbft : String
var gcm : String
}
class ViewController: UIViewController {
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet var tableView: UITableView!
let materialData = [
Material(name: "Acetaminohen Powder, Unmilled", lbft: "43", gcm: "0.688794"),
Material(name: "Acetylene Black, 100% Compressed", lbft: "35", gcm: "0.560646"),
Material(name: "Acetylsalicyic Acid", lbft: "20", gcm: "0.320369"),
Material(name: "Acrylamide", lbft: "34", gcm: "0.54463"),
Material(name: "Acrylic Granules, Coarse", lbft: "40", gcm: "0.64"),
Material(name: "Acrylic Granules, Fine", lbft: "36", gcm: "0.58"),
Material(name: "Acrylonitrile Butadien Styrene (Abs) Resin", lbft: "50", gcm: "0.8"),
Material(name: "Acrylonitrile Butadiene Styrene (Abs) Granules", lbft: "36", gcm: "0.58"),
Material(name: "Activated Alumina", lbft: "42.5", gcm: "0.68"),
Material(name: "Activated Carbon", lbft: "32.5", gcm: "0.52"),
Material(name: "Actylene Black", lbft: "45.5", gcm: "0.73"),
Material(name: "Aero Xanthates", lbft: "112.5", gcm: "1.8"),
Material(name: "Aerolyte", lbft: "51", gcm: "0.82"),
Material(name: "Aerosil, Fumed Silica", lbft: "32", gcm: "0.51"),
Material(name: "Aerosil, Silicon Dioxide", lbft: "30", gcm: "0.48"),
Material(name: "Alaluren", lbft: "112", gcm: "1.79")]
var searchMaterial = [String]()
var searching = false
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching {
return searchMaterial.count
} else {
return materialData.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.numberOfLines = 0
if searching {
cell.textLabel?.text = searchMaterial[indexPath.row]
} else {
cell.textLabel?.text = materialData[indexPath.row] // <-- ERROR Cannot assign value of type 'Material' to type 'String'
}
return cell
}
}
extension ViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchBar.setShowsCancelButton(true, animated: true)
searchMaterial = materialData.filter({[=11=].prefix(searchText.count) == searchText}) // <-- ERROR Cannot assign value of type '[Material]' to type '[String]'
// <-- ERROR Value of type 'Material' has no member 'prefix'
searching = true
tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.setShowsCancelButton(false, animated: true)
searching = false
searchBar.text = ""
tableView.reloadData()
}
}
没有
materialData[0] etc...
声明你的数组,例如
var searchMaterial:[String] = []
然后你可以像
一样访问它searchMaterial[indexPath.row]
1) cell.textLabel?.text = materialData[indexPath.row] materialData[indexPath.row] 将为您提供类型为 Material 而不是字符串的对象。不确定您期望的价值是多少。但将其更改为
materialData[indexPath.row].name
2) searchMaterial = materialData.filter({$0.prefix(searchText.count) == searchText}) // <-- 错误无法分配类型的值'[Material]' 键入 '[String]'
改为
var searchMaterial:[Material] = []
searchMaterial = materialData.filter { [=11=].name.contains(searchText) }
您要按 name
搜索吗?如果是这样,您可以像这样修复第二个 ERROR
:
searchMaterial = materialData
.map({ [=10=].name }) // convert to [String]
.filter { [=10=].hasPrefix(searchText) } // search
第一个可以这样修复:
cell.textLabel?.text = materialData[indexPath.row].name
嗨,肖恩,我相信我已经解决了这个问题,
您的 tableView 委托函数中的所有内容都是正确的
确保在顶层创建这个变量
var searchMaterial = [Material]()
然后将其添加到您的 searchBar 函数中:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
guard !searchText.isEmpty else {
searchMaterial = materialData
tableView.reloadData()
return // When no items are typed, load your array still
}
searchMaterial = materialData.filter({ (Material) -> Bool in
Material.title.lowercased().contains(searchText.lowercased())
})
searchBar.setShowsCancelButton(true, animated: true)
searching = true
tableView.reloadData()
希望对您有所帮助!!!