Ios 使用另一个视图控制器(带有表视图)显示UISearchController的结果
我有两个视图控制器。第一个CityViewController包含一个搜索栏,因此它的配置在那里完成。第二个是CitySearchViewController,用于显示搜索结果,我需要自定义单元格,这就是为什么我不简单地使用UITableViewController的原因。以下是用于在第一视图控制器内配置搜索控制器的代码:Ios 使用另一个视图控制器(带有表视图)显示UISearchController的结果,ios,swift,uitableview,uiviewcontroller,uisearchbar,Ios,Swift,Uitableview,Uiviewcontroller,Uisearchbar,我有两个视图控制器。第一个CityViewController包含一个搜索栏,因此它的配置在那里完成。第二个是CitySearchViewController,用于显示搜索结果,我需要自定义单元格,这就是为什么我不简单地使用UITableViewController的原因。以下是用于在第一视图控制器内配置搜索控制器的代码: class CityViewController: UIViewController { var searchController: UISearchController?
class CityViewController: UIViewController {
var searchController: UISearchController?
var citySearchViewController: CitySearchViewController?
override func viewDidLoad() {
super.viewDidLoad()
citySearchViewController = CitySearchViewController()
searchController = UISearchController(searchResultsController: citySearchViewController)
//Setting the search controller
setSearchController()
}
//Setting the search controller
private func setSearchController() {
if let searchController = searchController {
searchController.searchResultsUpdater = citySearchViewController
searchController.obscuresBackgroundDuringPresentation = true
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.placeholder = "Search for a city"
navigationItem.searchController = searchController
definesPresentationContext = true
searchController.searchBar.returnKeyType = .done
//searchController.searchBar.enablesReturnKeyAutomatically = false
searchController.searchBar.delegate = self
}
}
}
extension CityViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchController?.isActive = false
}
}
因此,我将第二个视图控制器CitySearchViewController设置为searchResultsController。在里面我有一个城市数组,视图控制器是数据源和表视图的委托,表视图在其中
以下是视图控制器内部的完整代码
class CitySearchViewController: UIViewController {
@IBOutlet weak var tableView: UITableView! {
didSet {
tableView.delegate = self
tableView.dataSource = self
}
}
let cities = [City(name: "Saint Petersburg", coordinates: CLLocation(latitude: 59.93863, longitude: 30.31413)), City(name: "Moscow", coordinates: CLLocation(latitude: 55.75222, longitude: 37.61556)), City(name: "London", coordinates: CLLocation(latitude: 51.509865, longitude: -0.118092)), City(name: "Chicago", coordinates: CLLocation(latitude: 41.881832, longitude: -87.623177)), City(name: "Sochi", coordinates: CLLocation(latitude: 43.588348, longitude: 39.729996)), City(name: "Madrid", coordinates: CLLocation(latitude: 40.416775, longitude: -3.703790)), City(name: "New York", coordinates: CLLocation(latitude: 40.730610, longitude: -73.935242)), City(name: "Paris", coordinates: CLLocation(latitude: 48.864716, longitude: 2.349014)), City(name: "Amsterdam", coordinates: CLLocation(latitude: 52.370216, longitude: 4.895168)), City(name: "Barcelona", coordinates: CLLocation(latitude: 41.390205, longitude: 2.154007))]
var filteredCities = [City]()
override func viewDidLoad() {
super.viewDidLoad()
}
private func filterContentForSearchText(_ searchText: String) {
filteredCities = cities.filter({ (city) -> Bool in
return city.name.lowercased().contains(searchText.lowercased())
})
tableView.reloadData()
}
extension CitySearchViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredCities.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "citySearchCell", for: indexPath) as! CitySearchTableViewCell
let filteredCity = filteredCities[indexPath.row]
cell.cityLabel.text = filteredCity.name
return cell
}
}
extension CitySearchViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
}
extension CitySearchViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
}
在那里,我进行了基本的表视图设置,还过滤了数组并相应地更新了表视图
问题是,只要我开始在搜索栏中点击一个单词,我就会得到一个异常。原因是CitySearchViewController中的表视图为零。因此,我认为,从CityViewController中的以下代码行初始化视图控制器时,我做错了一些事情:
class CityViewController: UIViewController {
var searchController: UISearchController?
var citySearchViewController: CitySearchViewController?
override func viewDidLoad() {
super.viewDidLoad()
citySearchViewController = CitySearchViewController()
searchController = UISearchController(searchResultsController: citySearchViewController)
//Setting the search controller
setSearchController()
}
//Setting the search controller
private func setSearchController() {
if let searchController = searchController {
searchController.searchResultsUpdater = citySearchViewController
searchController.obscuresBackgroundDuringPresentation = true
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.placeholder = "Search for a city"
navigationItem.searchController = searchController
definesPresentationContext = true
searchController.searchBar.returnKeyType = .done
//searchController.searchBar.enablesReturnKeyAutomatically = false
searchController.searchBar.delegate = self
}
}
}
extension CityViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchController?.isActive = false
}
}
我还尝试从故事板实例化视图控制器,但是,在这种情况下,我得到了一个错误,即在初始化过程中没有使用具有故事板ID的视图控制器。我已经检查并重新检查了视图控制器的id,它与代码中使用的id完全相同。以下是我尝试从第一个one CityViewController实例化CitySearchViewController的初始方法
class CitySearchViewController: UIViewController {
@IBOutlet weak var tableView: UITableView! {
didSet {
tableView.delegate = self
tableView.dataSource = self
}
}
let cities = [City(name: "Saint Petersburg", coordinates: CLLocation(latitude: 59.93863, longitude: 30.31413)), City(name: "Moscow", coordinates: CLLocation(latitude: 55.75222, longitude: 37.61556)), City(name: "London", coordinates: CLLocation(latitude: 51.509865, longitude: -0.118092)), City(name: "Chicago", coordinates: CLLocation(latitude: 41.881832, longitude: -87.623177)), City(name: "Sochi", coordinates: CLLocation(latitude: 43.588348, longitude: 39.729996)), City(name: "Madrid", coordinates: CLLocation(latitude: 40.416775, longitude: -3.703790)), City(name: "New York", coordinates: CLLocation(latitude: 40.730610, longitude: -73.935242)), City(name: "Paris", coordinates: CLLocation(latitude: 48.864716, longitude: 2.349014)), City(name: "Amsterdam", coordinates: CLLocation(latitude: 52.370216, longitude: 4.895168)), City(name: "Barcelona", coordinates: CLLocation(latitude: 41.390205, longitude: 2.154007))]
var filteredCities = [City]()
override func viewDidLoad() {
super.viewDidLoad()
}
private func filterContentForSearchText(_ searchText: String) {
filteredCities = cities.filter({ (city) -> Bool in
return city.name.lowercased().contains(searchText.lowercased())
})
tableView.reloadData()
}
extension CitySearchViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredCities.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "citySearchCell", for: indexPath) as! CitySearchTableViewCell
let filteredCity = filteredCities[indexPath.row]
cell.cityLabel.text = filteredCity.name
return cell
}
}
extension CitySearchViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
}
extension CitySearchViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
}
我没有使用另一个视图控制器来显示搜索控制器的结果,所以我想我做错了什么
如果您知道我做错了什么或知道正确的方法,我将感谢您的帮助。问题1
如果您正在通过以下方式初始化CitySearchViewController:
这意味着它将跳过您在Interface Builder中为该视图控制器在情节提要中设置的任何内容,最重要的是,将IBOutlet设置为tableView
问题2
您还指出,您试图用这行代码将其实例化为CitySearchViewController,但出现了一个错误,即找不到具有该标识符的VC:
citySearchViewController = UIStoryboard().instantiateViewController(withIdentifier: "searchCityTableView") as? CitySearchViewController
因为您没有指定脚本的名称来实例化VC,所以可能是错误的。您需要将情节提要的名称指定为:
citySearchViewController = UIStoryboard(name: "<storyboard filename here>", bundle: nil).instantiateViewController(withIdentifier: "searchCityTableView") as? CitySearchViewController
哪里有类似搜索故事板的东西,名为Search.storyboard好的,现在我明白原因了,谢谢。正如我在问题中所说的,我也尝试从故事板中实例化它,但是每次我得到关于id的错误时,我都会检查多次。知道为什么会这样吗?@TigranIskandaryan是的,把我的补充信息作为问题2Oh的一部分,太愚蠢了。。。感谢您的帮助,只要堆栈允许,我将接受您的回答:
citySearchViewController = UIStoryboard().instantiateViewController(withIdentifier: "searchCityTableView") as? CitySearchViewController
citySearchViewController = UIStoryboard(name: "<storyboard filename here>", bundle: nil).instantiateViewController(withIdentifier: "searchCityTableView") as? CitySearchViewController