为来自 API 的数据的 tableView 单元格设置 UISearchController
set up UISearchController for tableView cells for data coming from API
我真的很难为我的 tableView 实现 UISearchController,我按照 Sean Allen 的视频解释并像他一样做了,但我想问题出在我身上,我想不通。
我希望当用户想要搜索要实时更新的单元格时,他正在打字并且他将搜索的主要内容是 cell.veturaOutlet.text = currentVechicle.Plate
如果你有时间帮忙,请帮忙,因为我是 Swift 的新手,我真的很喜欢它,只是一开始每个人遇到的这些小问题
this is a pic of how the cells looks like!
class MonitorimiViewController: UIViewController {
@IBOutlet weak var monitorimiTableView: UITableView!
@IBOutlet weak var loaderMonitorimi: UIActivityIndicatorView!
var listOfVechicle: [Vehicles] = []
var filteredVehicles: [Vehicles] = []
var listOfVehicles = [Vehicles]()
override func viewDidLoad() {
super.viewDidLoad()
fetchAndReloadData()
configureSearchController()
loaderMonitorimi.hidesWhenStopped = true
loaderMonitorimi.startAnimating()
Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { [self] _ in
monitorimiTableView.reloadData()
configureTableView()
loaderMonitorimi.stopAnimating()
}
}
func configureTableView() {
monitorimiTableView.delegate = self
monitorimiTableView.dataSource = self
monitorimiTableView.rowHeight = 225
}
func configureSearchController() {
let searchController = UISearchController()
searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
searchController.searchBar.placeholder = "Search"
navigationItem.searchController = searchController
}
func fetchAndReloadData(){
APICaller.shared.getVehicles(for: APICaller.shared.id!) {[weak self] (result) in
guard let self = self else { return }
switch result {
case .success(let vehicle):
self.listOfVechicle = vehicle
DispatchQueue.main.async {
self.monitorimiTableView.reloadData()
}
case .failure(let error):
print(error)
}
}
}
}
extension MonitorimiViewController: UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating, UISearchBarDelegate{
func updateSearchResults(for searchController: UISearchController) {
guard let filter = searchController.searchBar.text, !filter.isEmpty else { return
}
filteredVehicles = filteredVehicles.filter { [=11=].Plate!.lowercased().contains(filter.lowercased()) }
monitorimiTableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listOfVechicle.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "monitorimiCell", for: indexPath) as? MyCustomCell1 else {return UITableViewCell()}
let currentVechicle = listOfVechicle[indexPath.row]
cell.veturaOutlet.text = currentVechicle.Plate
cell.shpejtsiaAktualeOutlet.text = currentVechicle.Speed!
cell.perditsuarOutlet.text = "\(currentVechicle.LastCommunicationDate!.convertToDisplayForm())"
cell.pasagjereOutlet.text = "\(currentVechicle.Passengers!) Person/a"
cell.vozitesiOutlet.text = "\(currentVechicle.Driver!)"
return cell
}
}
你可以使用这个:
var initialListOfVechicles: [Vehicles] = []
var vehicles: [Vehicles] = []
保留一个包含所有数据 (initialListOfVechicles
),另一个 (vehicles
) 用于操作列表(即过滤)并填充 tableView。
APICaller.shared.getVehicles(for: APICaller.shared.id!) {[weak self] (result) in
guard let self = self else { return }
switch result {
case .success(let vehicle):
self.initialListOfVechicles = vehicle
self.vehicles = self.initialListOfVechicles
...
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return vehicles.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "monitorimiCell", for: indexPath) as? MyCustomCell1 else {return UITableViewCell()}
let currentVechicle = vehicles[indexPath.row]
...
}
当你想过滤时:
func updateSearchResults(for searchController: UISearchController) {
guard let filter = searchController.searchBar.text, !filter.isEmpty else {
vehicles = initialListOfVechicles
monitorimiTableView.reloadData()
return
}
vehicles = initialListOfVechicles.filter { [=12=].Plate!.lowercased().contains(filter.lowercased()) }
monitorimiTableView.reloadData()
}
旁注:
[=15=].Plate!
如果 Plate
为 nil
,这将导致崩溃。即,为什么它在第一个地方是可选的?
建议以小写开头的变量命名,因此应该是 plate
而不是 Plate
。如果来自 JSON,你可以使用 CodingKeys
来正确匹配它们(即 plate
是键 Plate
),并使用 keyDecodingStrategy
.
我真的很难为我的 tableView 实现 UISearchController,我按照 Sean Allen 的视频解释并像他一样做了,但我想问题出在我身上,我想不通。
我希望当用户想要搜索要实时更新的单元格时,他正在打字并且他将搜索的主要内容是 cell.veturaOutlet.text = currentVechicle.Plate
如果你有时间帮忙,请帮忙,因为我是 Swift 的新手,我真的很喜欢它,只是一开始每个人遇到的这些小问题
this is a pic of how the cells looks like!
class MonitorimiViewController: UIViewController {
@IBOutlet weak var monitorimiTableView: UITableView!
@IBOutlet weak var loaderMonitorimi: UIActivityIndicatorView!
var listOfVechicle: [Vehicles] = []
var filteredVehicles: [Vehicles] = []
var listOfVehicles = [Vehicles]()
override func viewDidLoad() {
super.viewDidLoad()
fetchAndReloadData()
configureSearchController()
loaderMonitorimi.hidesWhenStopped = true
loaderMonitorimi.startAnimating()
Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { [self] _ in
monitorimiTableView.reloadData()
configureTableView()
loaderMonitorimi.stopAnimating()
}
}
func configureTableView() {
monitorimiTableView.delegate = self
monitorimiTableView.dataSource = self
monitorimiTableView.rowHeight = 225
}
func configureSearchController() {
let searchController = UISearchController()
searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
searchController.searchBar.placeholder = "Search"
navigationItem.searchController = searchController
}
func fetchAndReloadData(){
APICaller.shared.getVehicles(for: APICaller.shared.id!) {[weak self] (result) in
guard let self = self else { return }
switch result {
case .success(let vehicle):
self.listOfVechicle = vehicle
DispatchQueue.main.async {
self.monitorimiTableView.reloadData()
}
case .failure(let error):
print(error)
}
}
}
}
extension MonitorimiViewController: UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating, UISearchBarDelegate{
func updateSearchResults(for searchController: UISearchController) {
guard let filter = searchController.searchBar.text, !filter.isEmpty else { return
}
filteredVehicles = filteredVehicles.filter { [=11=].Plate!.lowercased().contains(filter.lowercased()) }
monitorimiTableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listOfVechicle.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "monitorimiCell", for: indexPath) as? MyCustomCell1 else {return UITableViewCell()}
let currentVechicle = listOfVechicle[indexPath.row]
cell.veturaOutlet.text = currentVechicle.Plate
cell.shpejtsiaAktualeOutlet.text = currentVechicle.Speed!
cell.perditsuarOutlet.text = "\(currentVechicle.LastCommunicationDate!.convertToDisplayForm())"
cell.pasagjereOutlet.text = "\(currentVechicle.Passengers!) Person/a"
cell.vozitesiOutlet.text = "\(currentVechicle.Driver!)"
return cell
}
}
你可以使用这个:
var initialListOfVechicles: [Vehicles] = []
var vehicles: [Vehicles] = []
保留一个包含所有数据 (initialListOfVechicles
),另一个 (vehicles
) 用于操作列表(即过滤)并填充 tableView。
APICaller.shared.getVehicles(for: APICaller.shared.id!) {[weak self] (result) in
guard let self = self else { return }
switch result {
case .success(let vehicle):
self.initialListOfVechicles = vehicle
self.vehicles = self.initialListOfVechicles
...
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return vehicles.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "monitorimiCell", for: indexPath) as? MyCustomCell1 else {return UITableViewCell()}
let currentVechicle = vehicles[indexPath.row]
...
}
当你想过滤时:
func updateSearchResults(for searchController: UISearchController) {
guard let filter = searchController.searchBar.text, !filter.isEmpty else {
vehicles = initialListOfVechicles
monitorimiTableView.reloadData()
return
}
vehicles = initialListOfVechicles.filter { [=12=].Plate!.lowercased().contains(filter.lowercased()) }
monitorimiTableView.reloadData()
}
旁注:
[=15=].Plate!
如果 Plate
为 nil
,这将导致崩溃。即,为什么它在第一个地方是可选的?
建议以小写开头的变量命名,因此应该是 plate
而不是 Plate
。如果来自 JSON,你可以使用 CodingKeys
来正确匹配它们(即 plate
是键 Plate
),并使用 keyDecodingStrategy
.