【问题标题】:Conditionally activate UISearchController for iOS8+有条件地为 iOS8+ 激活 UISearchController
【发布时间】:2016-02-02 18:55:32
【问题描述】:

我有一个应用程序,我想针对 iOS 7,但目前无法这样做,因为它包含仅适用于 iOS 8 及更高版本的 UISearchController。

我一直在尝试使用 UISearchDisplayController 修改搜索栏,以便它在 iOS 7 中工作,但我无法让它工作并且有点沮丧。所以作为一项临时措施(虽然我在编码方面做得更好),我想禁用任何低于 8.0 的 iOS 的搜索栏 - 这不会对最终用户产生太大影响,因为它在更大的应用程序中只有一个屏幕。

问题是我无法弄清楚如何有条件地执行此操作(例如,使用 "if #available(iOS 8.0, *)" ),因为变量 "searchController" 和 "controller" 是在外部定义的的方法或函数,因此不能有条件地分配。我猜条件语句只能在函数和方法中使用? (如您所见,仍在学习中)。

那么任何人都可以提供一种方法让我有条件地在此处禁用搜索栏,以便我可以定位 iOS 7 吗?我的这个类的代码如下。谢谢!

class RegData2: UITableViewController, UISearchResultsUpdating {

    let model = Model()
    var prevArray = [String]()
    var selectionPrev = String()

    var filteredTableData = [String]()

    var searchController = UISearchController()
    let controller = UISearchController(searchResultsController: nil)


    override func viewDidLoad() {
        super.viewDidLoad()


        self.searchController = ({
            controller.searchResultsUpdater = self
            controller.dimsBackgroundDuringPresentation = false
            controller.searchBar.sizeToFit()

            self.tableView.tableHeaderView = controller.searchBar
            self.definesPresentationContext = true

            return controller

        })()

        // Reload the table
        self.tableView.reloadData()

    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }


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

        if (self.searchController.active) && (controller.searchBar.text != "") {
            return self.filteredTableData.count
        }
        else {
            return prevArray.count
        }
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell!
        cell.textLabel?.font = UIFont.boldSystemFontOfSize(18)


        if (self.searchController.active) && (controller.searchBar.text != "") {
            cell.textLabel?.text = filteredTableData[indexPath.row]


            return cell
        }
        else {

            cell.textLabel?.text = prevArray[indexPath.row]

            return cell
        }
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
    {
        controller.searchBar.resignFirstResponder()
        performSegueWithIdentifier("regData2ToRegView", sender: self)    

    }       

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "regData2ToRegView" {

            let regView = segue.destinationViewController as! RegView
            let indexPath : NSIndexPath = self.tableView.indexPathForSelectedRow!
            var selection : String = prevArray[indexPath.row]
            if (self.searchController.active) && (self.controller.searchBar.text != "") {
                selection = self.filteredTableData[indexPath.row]
            }
            else {
                selection = self.prevArray[indexPath.row]
            }

            regView.prevSelection = selection
            regView.prevSelectionType = selectionPrev


        }

    }

    func updateSearchResultsForSearchController(searchController: UISearchController)
    {


        if searchController.searchBar.text != ""{

            filteredTableData.removeAll(keepCapacity: true)

            let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)

            if self.selectionPrev != "ed" {
                let array = (self.prevArray as NSArray).filteredArrayUsingPredicate(searchPredicate)
                filteredTableData = array as! [String]
//                edAlert = 0
            } else {
                let array = (self.prevArray as NSArray).filteredArrayUsingPredicate(searchPredicate)
                filteredTableData = array as! [String]
//                edAlert = 1
            }

            self.tableView.reloadData()

        } else  {

            self.tableView.reloadData()
        }

    }

}

【问题讨论】:

    标签: swift ios7 uisearchbar uisearchdisplaycontroller uisearchcontroller


    【解决方案1】:

    要检查版本,您可以这样做:

    switch UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch) {
    case .OrderedSame, .OrderedDescending:
        println("iOS >= 8.0")
    case .OrderedAscending:
        println("iOS < 8.0")
    }
    

    但很可能您只需要检查该类是否可用,然后实例化它:

    if NSClassFromString("UISearchController") != nil { 
        // init and use ...
    }
    

    这称为“弱链接”类。

    编辑:
    您还可以使用预处理器在编译之前包含/排除任何代码,即:

    #if __IPHONE_8_0
        class RegData2: UITableViewController, UISearchResultsUpdating {
    #else
        class RegData2: UITableViewController {
    #endif
    

    更多信息 herehere 以及 here

    【讨论】:

    • 感谢您的回复。虽然问题不在于如何检查版本或如何有条件地实例化 - 我知道如何做到这两点。问题是您不能在函数或方法之外使用 switch 语句或条件。这是一个问题,因为“searchController”是在任何函数或方法之外初始化的。所以我无法检查 iOS 版本。
    • 我用另一种解决方案编辑了我的答案,更合适的解决方案:)
    • 距离更近一点 - 再次感谢您在这里的输入。但我还没到。将我的课程包装在“#if __IPHONE_8_0”语句中似乎不起作用。我在“#if”代码和“#else”代码中放置了一个断点,当我运行它时会跳到“#else”代码。看起来它无法识别“__IPHONE_8_0”或至少无法识别我的设备和模拟器满足此条件。我还尝试将其更改为“__IPHONE_9_0”和“__IPHONE_9_2”,因此它与我设备的 iOS 完全匹配,但仍然没有。想法?
    • 做一些研究,似乎 Swift 从 Objective-C 中拿走了很多预处理器代码。现在它仅限于检查构建(例如,iOS、WatchOS、OS X 等)。但不能做版本控制。有人有其他想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    • 1970-01-01
    相关资源
    最近更新 更多