UISearchController 保留问题

Posted

技术标签:

【中文标题】UISearchController 保留问题【英文标题】:UISearchController retain issue 【发布时间】:2015-08-21 13:09:21 【问题描述】:

我正在尝试使用 UISearchController,但是我遇到了无法解决的保留问题。 MainTableview 有两个部分。

第 1 节

根据一些正则表达式过滤数据

第 2 节

所有数据

我将 UISearchController 添加到我的 tableview 并将 ResultsTableController 附加为 resultsTableController。它在用户搜索某些内容时起作用,ResultsTableController 出现并且因为我将 tableview 委托设置为 self,从 ResultsTableController 中选择项目调用了 MainTableViewController 中的 didSelectRowAtIndexPath。但是,如果用户从 resultsTableController 中选择某些内容,我会遇到分配问题。

以下情况发生在不同的场景中

用户不搜索任何内容,只是从中选择一个项目 MainTableview,我看到了 deinit 消息 用户搜索某项,取消搜索,选择项目 MainTableview,我看到了 deinit 消息 用户搜索某些内容,然后从 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")
    

【问题讨论】:

【参考方案1】:

嘿,我今天遇到了这个问题 显然我需要强制解除 searchController 以解决保留问题

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

这是我的示例项目 https://www.dropbox.com/s/zzs0m4n9maxd2u5/TestSearch.zip?dl=0

【讨论】:

正确,谢谢。看来UISearchController 本身不太擅长清理。 天啊,在这个愚蠢的问题上只花了 2 个小时。谢谢!!【参考方案2】:

解决方案似乎是在某个时候在 UISearchController 上调用dismissViewControllerAnimated。大多数人可能不会这样做,因为 UISearchController 在某种程度上是与托管 UISearchController 的视图控制器相关的实现细节。

我的解决方案,无论您如何呈现搜索 UI(标准呈现或在弹出窗口中)似乎都有效,是在检查视图控制器是否不再存在后,从主机的 viewDidDisappear 调用 searchController.dismissViewControllerAnimated()被呈现。这适用于所有情况,尤其是用户在弹出框之外点击以自动关闭 UI 的弹出框情况,或者只是因为您将其他内容推到导航堆栈上而导致搜索 UI 消失的情况。在后一种情况下,您不想关闭 UISearchController。

override func viewDidDisappear(animated: Bool)

    super.viewDidDisappear(animated)

    if presentingViewController == nil
    
        searchController.dismissViewControllerAnimated(false, completion: nil)
    

【讨论】:

以上是关于UISearchController 保留问题的主要内容,如果未能解决你的问题,请参考以下文章

为 UISearchBar 保留边距

当我删除它们时,UISearchController 不会删除结果

保留UISearchBar的边距

使用 UISearchBar 作为 UITableView 的标题视图不可避免的保留周期?

iOS有没有办法在活动时将UISearchBar保留在TableviewHeader中

UISearchController 没有响应