Использование другого контроллера представления (с представлением таблицы), чтобы показать результаты UISearchController - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть два контроллера представления.Первый (CityViewController) содержит панель поиска, поэтому ее настройка выполняется там.Второй (CitySearchViewController) используется для отображения результатов поиска (мне нужны пользовательские ячейки, поэтому я просто не использую UITableViewController).Вот код для настройки search controller внутри первого контроллера вида:

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 равно nil.Итак, я думаю, что я делаю что-то не так, когда инициализирую контроллер представления из этих строк кода внутри CityViewController:

override func viewDidLoad() {
super.viewDidLoad()


citySearchViewController = CitySearchViewController()
searchController = UISearchController(searchResultsController: citySearchViewController)

//Setting the search controller
setSearchController()
}

Я также пытался создать экземпляр контроллера представления из раскадровки, однакоВ этом случае я получил сообщение об отсутствии контроллера представления с storyboardId, используемого во время инициализации.Я проверил и перепроверил id контроллера представления, и он был точно таким же, как тот, который использовался в коде.Вот первоначальный способ, которым я пытался создать экземпляр CitySearchViewController из первого (CityViewController).

override func viewDidLoad() {
    super.viewDidLoad()

    citySearchViewController = UIStoryboard().instantiateViewController(withIdentifier: "searchCityTableView") as? CitySearchViewController

    //Setting the search controller
    setSearchController()
}

Я не использовал другой контроллер представления для отображения результатов поиска.контроллер, так что я думаю, что я делаю что-то не так.

Если вы знаете, что я делаю неправильно или знаете правильный способ сделать это, я был бы признателен за вашу помощь.

1 Ответ

0 голосов
/ 25 апреля 2018

Задача № 1

Если вы инициализируете CitySearchViewController через:

citySearchViewController = CitySearchViewController()

Это означает, что он пропускает то, что вы настроили в раскадровке в Интерфейсном Разработчике для этого контроллера представления - и, самое главное, от IBOutlet до tableView

@IBOutlet weak var tableView: UITableView!

Задача № 2

Вы также указываете, что пытались создать экземпляр CitySearchViewController с этой строкой кода с ошибкой, что VC с этим идентификатором не найден:

citySearchViewController = UIStoryboard().instantiateViewController(withIdentifier: "searchCityTableView") as? CitySearchViewController

Поскольку вы не указали название раскадровки для создания экземпляра VC, возможно, это неправильно. Вам нужно указать название раскадровки как:

citySearchViewController = UIStoryboard(name: "<storyboard filename here>", bundle: nil).instantiateViewController(withIdentifier: "searchCityTableView") as? CitySearchViewController

(где <storyboard filename here> - это что-то вроде «Поиск» для раскадровки с именем «Search.storyboard»)

...