Swift iOS SearchController 未在 ViewDidLoad 中调用

Posted

技术标签:

【中文标题】Swift iOS SearchController 未在 ViewDidLoad 中调用【英文标题】:Swift iOS SearchController not Being Called in ViewDidLoad 【发布时间】:2016-12-22 06:42:33 【问题描述】:

我有一个搜索控制器,他的视图是从另一个视图控制器呈现的。基本上我在另一个视图中有一个 NavBarButton,当我按下它时会显示 searchcontoller。

由于某种原因,在 viewDidLoad 中没有调用搜索控制器。知道为什么吗?

顺便说一句,我没有添加 tableView 方法,因为那不是我遇到问题的地方。当我在var searchController: UISearchController! 上设置一个断点时,它就会命中。

在 viewDidLoad 内部,当我在 searchController(anything) 上放置断点时,它会跳过它,所以这就是问题所在。

numberOfRowsInSection... 内部,当我在let scopeButtonIndex = self.searchController.searchBar.selectedScopeButtonIndex 上设置断点并按继续时,它会在此处崩溃,因为 selectedScopeButtonIndex 返回 Nil 值。我意识到它是 nil,因为它没有在 viewDidLoad self.searchController.searchBar.scopeButtonTitles = ["Sneaker Name","Sneaker Condition"] 中被调用

为什么 viewDidLoad 没有调用我的 searchController?

class SearchViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchResultsUpdating, UISearchBarDelegate, UISearchControllerDelegate 

@IBOutlet weak var tableView: UITableView!

var searchController: UISearchController!

var userContent = [Sneakers]()
var filteredSearchSneakerNames = [Sneakers]()
var filteredSearchSneakerConditions = [Sneakers]()

override func viewDidLoad() 
        super.viewDidLoad()

        let backgroundColor = UIView(frame: CGRectZero)
        self.tableView.tableFooterView = backgroundColor

        //Nothing below this comment inside viewDidLoad is being called 
        self.tableView.backgroundColor = UIColor.whiteColor()
        self.searchController = UISearchController(searchResultsController: nil)
        self.searchController.delegate = self
        self.searchController.searchBar.delegate = self
        self.searchController.searchResultsUpdater = self
        self.searchController.searchBar.showsCancelButton = true
        self.searchController.searchBar.placeholder = "Search..."
        self.searchController.searchBar.scopeButtonTitles = ["Sneaker Name","Sneaker Condition"]
        self.searchController.searchBar.returnKeyType = .Done
        self.navigationItem.hidesBackButton = true
        self.searchController.dimsBackgroundDuringPresentation = false
        self.navigationItem.titleView = searchController.searchBar
        self.searchController.hidesNavigationBarDuringPresentation = false
        self.definesPresentationContext = true
        self.searchController.searchBar.sizeToFit()
        self.tableView.tableHeaderView = self.searchController.searchBar
        self.tableView.reloadData()
    

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

    //I put a breakpoint here and it crashes
    let scopeButtonIndex = self.searchController.searchBar.selectedScopeButtonIndex

    if scopeButtonIndex == 0
        return self.filteredSearchSneakerNames.count
    else
        return self.filteredSearchSneakerConditions.count
    


func tableView(tableView: UITableView, cellForRowAtIndexPath...)
...


deinit
        self.searchController = nil
    


我没有添加 updateSearchResultsForSearchController 或任何其他 searchController 方法,因为它们没有任何问题。

【问题讨论】:

【参考方案1】:

尝试将这两行移到 viewDidLoad 的末尾。您的表格视图作为 IBOutlet 来自情节提要,这意味着它们在 viewDidLoad 之前准备就绪,在 tableview 上调用方法 tableFooterView 会触发方法 tableView:cellForRowAtIndexPath。由于此时您的 self.searchController 尚未设置,因此您将得到 nil 并崩溃。将这两行移到最后可确保在您的数据源可用(在本例中为 searchController)之后开始对 table view 的操作。

let backgroundColor = UIView(frame: CGRectZero)
self.tableView.tableFooterView = backgroundColor

或者,您可以在self.searchController.searchBar.selectedScopeButtonIndex 中检查 nil,如果为 true,则在 numberOfRowsInSection 中返回 0,这样可以避免崩溃。当你调用self.tableView.reloadData() 时,它会再次触发numberOfRowsInSection,这一次self.searchController.searchBar.selectedScopeButtonIndex 应该准备好了,而不是nil。

【讨论】:

以上是关于Swift iOS SearchController 未在 ViewDidLoad 中调用的主要内容,如果未能解决你的问题,请参考以下文章

iOS-Swift-UIView

iOS开发中OC和swift的对比

ios OC、swift混编制作framework

iOS-swift-基础篇1

iOS开发系列--Swift 3.0

swift 2016年 - iOS / PlayerViewController.swift