使用 UISearchController 将获取的数据填充到 tableView
populate fetched data to tableView using UISearchController
我正在从 API 中获取数据,当我在控制台中输入城市时工作正常。我现在面临的问题是下面代码中的 UISearchController 和 tableView 我想在 tableView 中填充我搜索的城市。现在,当我 运行 该应用程序时它不会显示任何内容,除了在我的控制台中记录我在搜索栏中搜索时的请求
日志:
Search text: London
Creating request..
Task started
City name: London
Success! JSON decoded
这意味着将搜索功能与 API 请求一起使用是可行的,只是我在我的 tableView 中看不到它
这是我的 viewController
import UIKit
class ViewController: UIViewController{
@IBOutlet weak var tblView: UITableView!
let mWeather = WeatherAPI()
var weatherArray = [WeatherStruct]()
var filteredWeatherArray : [String] = []
// dummy data
let originalArray = ["gothenburg", "london", "stockholm", "new york", "washington DC", "thailand", "china", "spain", "paris"]
var searching: Bool {
if weatherArray.count > 0 {
return true
} else {
return false
}
}
let searchController: UISearchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "type in your city here"
navigationItem.searchController = searchController
tblView.delegate = self
tblView.dataSource = self
}
}
// MARK: - extensions
extension ViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
let searchText = searchController.searchBar.text ?? "can not search"
print("Search text: \(searchText)")
mWeather.fetchCurrentWeather(city: searchText) { (WeatherStruct) in}
tblView.reloadData()
}
}
// MARK: - Table view data source
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching {
return weatherArray.count // when something is typed on searchbar
}else{
return filteredWeatherArray.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "searchCell", for: indexPath)
if searching {
cell.textLabel?.text = weatherArray[indexPath.row].name
tblView.reloadData()
} else {
cell.textLabel?.text = filteredWeatherArray[indexPath.row]
tblView.reloadData()
}
return cell
}
}
编辑:因为这可能会帮助别人帮助我 = API 请求处理程序
func fetchCurrentWeather(city: String, completionHandler: @escaping (WeatherStruct) -> Void) {
// url
let wholeUrl = baseUrlForCurrentWeather + city + appid + metric
let urlString = (wholeUrl)
guard let url: URL = URL(string: urlString) else { return }
// Request
print("Creating request..")
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let unwrappedError = error {
print("Nått gick fel. Error: \(unwrappedError)")
return
}
if let unwrappedData = data {
do {
let decoder = JSONDecoder()
let wdata: WeatherStruct = try decoder.decode(WeatherStruct.self, from: unwrappedData)
print("City name: \(String(describing: wdata.name))")
print("Success! JSON decoded")
completionHandler(wdata)
} catch {
print("Couldnt parse JSON..")
print(error)
}
}
}
// Starta task
task.resume()
print("Task started")
}
您需要根据在 updateSearchResults(for searchController
方法中从 fetchCurrentWeather
获得的结果更新 filteredWeatherArray
,方法如下:
mWeather.fetchCurrentWeather(city: searchText) { weather in
self.weatherArray = [weather]
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
编辑:即使上面的代码可能对您有用,您也可能得不到想要的结果。您正在尝试显示 weatherArray
数组中的列表,但是当您调用 fetchCurrentWeather
时,您只会得到一个结果。我修改了我的代码以将一个数组元素设置为 weatherArray
并重新加载。
我正在从 API 中获取数据,当我在控制台中输入城市时工作正常。我现在面临的问题是下面代码中的 UISearchController 和 tableView 我想在 tableView 中填充我搜索的城市。现在,当我 运行 该应用程序时它不会显示任何内容,除了在我的控制台中记录我在搜索栏中搜索时的请求
日志:
Search text: London
Creating request..
Task started
City name: London
Success! JSON decoded
这意味着将搜索功能与 API 请求一起使用是可行的,只是我在我的 tableView 中看不到它
这是我的 viewController
import UIKit
class ViewController: UIViewController{
@IBOutlet weak var tblView: UITableView!
let mWeather = WeatherAPI()
var weatherArray = [WeatherStruct]()
var filteredWeatherArray : [String] = []
// dummy data
let originalArray = ["gothenburg", "london", "stockholm", "new york", "washington DC", "thailand", "china", "spain", "paris"]
var searching: Bool {
if weatherArray.count > 0 {
return true
} else {
return false
}
}
let searchController: UISearchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "type in your city here"
navigationItem.searchController = searchController
tblView.delegate = self
tblView.dataSource = self
}
}
// MARK: - extensions
extension ViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
let searchText = searchController.searchBar.text ?? "can not search"
print("Search text: \(searchText)")
mWeather.fetchCurrentWeather(city: searchText) { (WeatherStruct) in}
tblView.reloadData()
}
}
// MARK: - Table view data source
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching {
return weatherArray.count // when something is typed on searchbar
}else{
return filteredWeatherArray.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "searchCell", for: indexPath)
if searching {
cell.textLabel?.text = weatherArray[indexPath.row].name
tblView.reloadData()
} else {
cell.textLabel?.text = filteredWeatherArray[indexPath.row]
tblView.reloadData()
}
return cell
}
}
编辑:因为这可能会帮助别人帮助我 = API 请求处理程序
func fetchCurrentWeather(city: String, completionHandler: @escaping (WeatherStruct) -> Void) {
// url
let wholeUrl = baseUrlForCurrentWeather + city + appid + metric
let urlString = (wholeUrl)
guard let url: URL = URL(string: urlString) else { return }
// Request
print("Creating request..")
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let unwrappedError = error {
print("Nått gick fel. Error: \(unwrappedError)")
return
}
if let unwrappedData = data {
do {
let decoder = JSONDecoder()
let wdata: WeatherStruct = try decoder.decode(WeatherStruct.self, from: unwrappedData)
print("City name: \(String(describing: wdata.name))")
print("Success! JSON decoded")
completionHandler(wdata)
} catch {
print("Couldnt parse JSON..")
print(error)
}
}
}
// Starta task
task.resume()
print("Task started")
}
您需要根据在 updateSearchResults(for searchController
方法中从 fetchCurrentWeather
获得的结果更新 filteredWeatherArray
,方法如下:
mWeather.fetchCurrentWeather(city: searchText) { weather in
self.weatherArray = [weather]
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
编辑:即使上面的代码可能对您有用,您也可能得不到想要的结果。您正在尝试显示 weatherArray
数组中的列表,但是当您调用 fetchCurrentWeather
时,您只会得到一个结果。我修改了我的代码以将一个数组元素设置为 weatherArray
并重新加载。