Итак, удаляя беспорядок, вы, по сути, делаете это ...
self.cityNames.removeAll()
for str in cityNames {
//...
cityNames.append(str)
}
Вы удаляете все элементы из массива и пытаетесь перебрать его, но, поскольку сейчас ничего нет в массиве перебирать нечего.
Вы можете использовать «отфильтрованный» массив, который получает данные из массива «master». «Фильтрованный» массив - это то, что будет отображаться пользователю
var filteredCities: [String]()
private func populateCities() {
BasicInfoServices.shared.getCity { [weak self] result in
switch result {
case .success(let cities):
self?.cities = cities
let names = cities.compactMap { $0.name }
self?.cityNames = names
self?.filteredCities = names
case .failure(let error):
print(error)
}
}
}
Затем, когда вам нужно отфильтровать список ...
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if searchTextField.text?.count != nil {
self.filteredCities.removeAll()
for str in cityNames {
let range = str.lowercased().range(of: textField.text!, options: .caseInsensitive, range: nil, locale: nil)
if range != nil {
filteredCities.append(str)
}
}
}
tableView.reloadData()
return true
}
Это, конечно, будет означать, что вы будете нужно использовать filteredCities
вместо cityNames
в вашем источнике данных таблицы;)
Сказав все это. Я бы подумал сделать что-то немного по-другому. Вместо использования списков мастер / фильтр, просто используйте массив cities
как мастер и фильтруйте его напрямую ...
if let text = searchTextField.text, !text.isEmpty else {
cityNames = cities.filter { $0.name.lowercased().range(of: text, options: .caseInsensitive, range: nil, locale: nil) != nil }.map { $0.name }
} else {
cityNames = cities.map { $0.name }
}
Если скорость является проблемой, вы можете вернуться к списку мастер / фильтр String
значений, которые позволят вам убрать необходимость map
результатов, но на этом этапе я бы задался вопросом, зачем вам нужен список String
в любом случае
Например ...
var cities = [City]() // Master
var cityFilter = [City]() // Filter
private func populateCities() {
BasicInfoServices.shared.getCity { [weak self] result in
switch result {
case .success(let cities):
self?.cities = cities
self?.cityFilter = cities
case .failure(let error):
print(error)
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cityFilter.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CitiesAlertCell.cellId, for: indexPath) as! CitiesAlertCell
cell.selectionStyle = .none
let item = cityFilter[indexPath.row]
cell.item = item // The item is now a city reference
return cell
}
func textFieldShouldClear(_ textField: UITextField) -> Bool {
searchTextField.resignFirstResponder()
cityFilter = cities
return true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if let text = searchTextField.text, !text.isEmpty else {
cityFilter = cities.filter { $0.name.lowercased().range(of: text, options: .caseInsensitive, range: nil, locale: nil) != nil }
} else {
cityFilter = cities
}
tableView.reloadData()
return true
}
Если вы беспокоитесь о городах с nil
названиями, то я бы filter
исходный список, так что основной список содержал только допустимые значения