UISearchController сохраняет проблему

Я пытаюсь использовать UISearchController, однако столкнулся с проблемой сохранения, которую не могу решить. MainTableview состоит из двух разделов.

Секция 1

Отфильтрованные данные на основе некоторых регулярных выражений

Раздел 2

Все данные

Я добавил UISearchController в свое табличное представление и прикрепил ResultsTableController в качестве resultsTableController. Это работает, когда пользователь что-то ищет, ResultsTableController выходит вперед, и поскольку я устанавливаю делегата tableview на себя, выбор элемента из вызовов ResultsTableController didSelectRowAtIndexPath в моем MainTableViewController. Однако у меня есть проблема с распределением, если пользователь выбирает что-то из resultsTableController.

Следующее происходит для разных сценариев

  • Пользователь ничего не ищет, просто выбирает элемент из MainTableview, я вижу сообщения deinit
  • Пользователь что-то ищет, отменить поиск, выбрать элемент из MainTableview, я вижу сообщения о деинициализации
  • Пользователь что-то ищет и выбирает элемент из ResultsTableController, я не получаю deinit в своих контроллерах представления

MainTableViewController.swift

var searchController: UISearchController!

// Secondary search results table view.
var resultsTableController: ResultsTableController!
var allCompanies = ["Data1","Data2","Data3"]

override func viewDidLoad() {
    super.viewDidLoad()
     resultsTableController = ResultsTableController()
    // We want to be the delegate for our filtered table so didSelectRowAtIndexPath(_:) is called for both tables.
    resultsTableController.tableView.delegate = self
    searchController = UISearchController(searchResultsController: resultsTableController)
    searchController.searchResultsUpdater = self
    searchController.searchBar.sizeToFit()
    tableView.tableHeaderView = searchController.searchBar

    searchController.delegate = self
    searchController.dimsBackgroundDuringPresentation = false 
    searchController.searchBar.delegate = self   
    definesPresentationContext = true
    }
}



// MARK: UISearchBarDelegate

func searchBarSearchButtonClicked(searchBar: UISearchBar) {
    searchBar.resignFirstResponder()
}

// MARK: UISearchResultsUpdating
func updateSearchResultsForSearchController(searchController: UISearchController) {
    // Update the filtered array based on the search text.

    let filteredResults = allCompanies.filter({ company in
        (company.lowercaseString as NSString).containsString(searchController.searchBar.text.lowercaseString)
    })

    // Hand over the filtered results to our search results table.
    let resultsController = searchController.searchResultsController as! ResultsTableController
    resultsController.searchResult = filteredResults
    resultsController.tableView.reloadData()
}

// usual tableview methods

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        if resultsTableController.searchResult.count > 0 {
        selectedCompany = resultsTableController.searchResult[index]
        //do something with selected company
        navigationController?.popViewControllerAnimated(true)
        return
     }
     //
     selectedCompany = allCompanies[index]
      navigationController?.popViewControllerAnimated(true)

}

deinit {
    println("MainTableView deinit")
}

ResultTableController.swift

class ResultsTableController:UITableViewController {

     var searchResult = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
     }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return searchResult.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
        let index = indexPath.row
        cell.textLabel?.font = UIFont(name: "Avenir-Roman", size: 16)
        cell.textLabel?.text = searchResult[index].description
        return cell

    }

    deinit {
        println("ResultTableController deinit")
    }
}

person Meanteacher    schedule 21.08.2015    source источник


Ответы (2)


Эй, сегодня я столкнулся с проблемой, видимо, мне нужно принудительно закрыть searchController, чтобы обойти проблему с сохранением.

  override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    searchController?.dismissViewControllerAnimated(false, completion: nil)
  }

вот мой пример проекта https://www.dropbox.com/s/zzs0m4n9maxd2u5/TestSearch.zip?dl=0

person Pierre    schedule 09.11.2015
comment
В точку, спасибо. Кажется, UISearchController не очень хорошо убирает за собой. - person Stuart; 23.02.2016
comment
Боже только что потратил 2 часа на эту глупую проблему. Спасибо!! - person Khanh Nguyen; 22.04.2021

Похоже, что решение состоит в том, чтобы в какой-то момент вызвать уволить ViewControllerAnimated в UISearchController. Большинство людей, вероятно, не делают этого, так как UISearchController является чем-то вроде детали реализации, связанной с вашим контроллером представления, на котором размещается UISearchController.

Мое решение, которое, кажется, работает независимо от того, как вы представляете свой поисковый пользовательский интерфейс (стандартный или во всплывающем окне), состоит в том, чтобы вызвать searchController.dismissViewControllerAnimated() из viewDidDisappear вашего хоста после проверки, чтобы увидеть, не отображается ли контроллер представления. Это охватывает все случаи, особенно случай с всплывающим окном, когда пользователь касается вне всплывающего окна, чтобы автоматически закрыть пользовательский интерфейс, или случай, когда пользовательский интерфейс поиска исчезает просто потому, что вы добавили что-то еще в стек навигации. В последнем случае вы не хотите отклонять UISearchController.

override func viewDidDisappear(animated: Bool)
{
    super.viewDidDisappear(animated)

    if presentingViewController == nil
    {
        searchController.dismissViewControllerAnimated(false, completion: nil)
    }
}
person Mark Krenek    schedule 11.07.2016