问题描述
目前我正在尝试实现我的搜索栏,但出了点问题,我无法弄清楚它是什么。这是代码和解释。
//global variable for empty array,its type of Any cause I am getting data from network call
var filteredData: [Any]!
//these are my models,which I am using to display them on screen after mapping in network function
var bookedTrips: [BookedTripsForView]?
func viewDidLoad() {
super.viewDidLoad()
filteredData = bookedTrips
}
func searchBar(_ searchBar: UISearchBar,textDidChange searchText: String) {
searchBar.becomeFirstResponder()
filteredData = []
if searchText == "" {
filteredData = bookedTrips
}else {
for trip in (bookedTrips)! {
if trip.tripName.lowercased().contains(searchText.lowercased()){
filteredData.append(trip)
//if I type,lets say Barcelona,in console its printed correct result,//but its displaying only first trip in my array,which is Berlin
print("filteredDataArray after appending print: \(String(describing: filteredData))")
}
}
}
self.tableView.reloadData()
}
我希望我的解释没问题,如果有不清楚的地方,我会重构我的问题。提前致谢。
Here is picture of my screen and console
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
if let filter = filteredData {
return filter.count
} else if let data = bookedTrips {
return data.count
}
return 0
}
func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Cells.tripInfo) as! TripsListDetailCell
if let trips = bookedTrips?[indexPath.row] {
cell.configure(trips: trips)
}
return cell
}
解决方法
简短而简单(单行过滤器)
var filteredData = [BookedTripsForView]()
var bookedTrips = [BookedTripsForView]()
override func viewDidLoad() {
super.viewDidLoad()
bookedTrips = fetchFromAPIorDB()
filteredData = bookedTrips
}
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
return self.filteredData.count
}
func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Cells.tripInfo) as! TripsListDetailCell
cell.configure(trips: filteredData[indexPath.row])
return cell
}
func searchBar(_ searchBar: UISearchBar,textDidChange searchText: String) {
if searchText.isEmpty {
filteredData = bookedTrips
}
else {
filteredData = bookedTrips.filter({ $0.tripName.lowercased().contains(searchText.lowercased()) })
}
self.tableView.reloadData()
}
,
为可读代码创建这样的页面情绪枚举:
enum PageMood {
case normal
case search
}
并创建变量
var pageMode: PageMood = .normal
如果搜索和更改 pageMode 为这样搜索,则首先将其设置为正常:
func searchBar(_ searchBar: UISearchBar,textDidChange searchText: String) {
searchBar.becomeFirstResponder()
if searchText == "" {
pageMode = .normal
}else {
pageMode = .search
filteredData = bookedTrips?.filter({ item -> Bool in
return (item.tripName?.lowercased().contains(searchText.lowercased()) ?? false)
})
}
self.tableView.reloadData()
}
像这样更改定义数据源:
var bookedTrips: [BookedTripsForView]?
var filteredData: [BookedTripsForView]?
和内部集合 numberOfItem:
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
if pageMode == .search {
return filteredData.count ?? 0
} else {
return bookedTrips.count ?? 0
}
}
如果只找到一项,可能您的数据中只有一项与搜索文本相似。
, var isSearching: Bool = false // As global variable
var bookedTrips: [BookedTripsForView]? = []
var filteredData: [BookedTripsForView]? = []
func searchBar(_ searchBar: UISearchBar,textDidChange searchText: String) {
searchBar.becomeFirstResponder()
filteredData = []
if searchText == "" {
isSearching = false
}else {
isSearching = true
filteredData = bookedTrips.filter { (trip) -> Bool in
if trip.tripName.lowercased().contains(searchText.lowercased()){
return true
}
return false
}
}
self.tableView.reloadData()
}
//Tableview 委托
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
if isSearching {
return self.filteredData.count
}
return bookedTrips.count
}
func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Cells.tripInfo) as! TripsListDetailCell
if isSearching {
cell.configure(trips: filteredData[indexPath.row])
}
else {
cell.configure(trips: bookedTrips[indexPath.row])
}
return cell
}
,现在,由于我将变量更改为:
var filteredData = [BookedTripsForView]()
var bookedTrips = [BookedTripsForView]()
我在部分还有一个问题,在里面添加了评论
func tableView(_ tableView: UITableView,viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableHeaderFooterView(withIdentifier: Cells.sectionTitle) as! TripsListHeaderCell
if isSearching {
cell.configure(trips: filteredData[section])
}
else {
cell.configure(trips: bookedTrips[section])
}
return cell
}
我应该如何实现函数viewForHeaderInSection?作为对每次旅行的回应,我都会得到旅行的状态(当前、即将到来的、以前的)。我想按状态对它们进行排序。如果我把它放在 viewForHeaderInSection 中:
if isSearching {
cell.configure(trips: filteredData[section])
} else {
cell.configure(trips:bookedTrips[section])
}
return cell
我在 bookedTrips[section] 上的索引超出范围如果我评论那行,它会一直工作,直到我在搜索栏中出错,假设我输入 Bars 而不是 Barcelona,它会在 filtersData[section] 索引上抛出错误范围
在我的回复中,每次旅行都有属于字符串类型的旅行状态属性,我什至可以按该属性对它们进行排序吗?