0

I have an app that I would like to target to iOS 7, but am currently unable to do so because it contains a UISearchController which is only available for iOS 8 and up.

I've been trying to modify the search bar with a UISearchDisplayController so that it works in iOS 7, but I just can't get it to work and am getting a little frustrated. So as a temporary measure (while I get better at coding), I would like to disable the search bar for any iOS below 8.0 - which won't impact the end user too much because its only one screen in a much larger app.

The problem is that I haven't been able to figure out how to do this conditionally (e.g., with "if #available(iOS 8.0, *)" ) because the variables "searchController" and "controller" are defined outside of a method or function and so can't be assigned conditionally. I guess conditional statements can only be used within functions and methods? (still learning, as you can see).

So can anyone offer a way for me to conditionally disable the search bar here so I can target iOS 7? My code for this class is below. Thanks!

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()
        }

    }

}
TJ Rogers
  • 500
  • 1
  • 6
  • 19

1 Answers1

0

To check version you can do this:

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

But most likely you just need to check if the class is available and then instantiate it:

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

This is called "weakly linked" class.

EDIT:
Also you can use preprocessor to include/exclude any code before compilation, i.e.:

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

More info here and here and also here.

Community
  • 1
  • 1
scope
  • 1,967
  • 14
  • 15
  • Thank you for your reply. Although the problem is not how to check version or how to conditionally instantiate - I know how to do both of those. The problem is that you can't use a switch statement or a conditional outside a function or method. This is a problem because "searchController" is initialized outside any functions or methods. So I can't check for iOS version on this. – TJ Rogers Feb 02 '16 at 19:45
  • I edited my answer with yet another solution, more fitting one :) – scope Feb 02 '16 at 20:00
  • Getting a little closer - and thank you again btw, for your input here. But I'm not there yet. Wrapping my class in the "#if __IPHONE_8_0" statement does not seem to work. I put a breakpoint in the "#if" code and the "#else" code, and when I run it skips down to the "#else" code. Looks like it's not recognizing "__IPHONE_8_0" or at least not recognizing my device and simulator as meeting this condition. I also tried changing it to "__IPHONE_9_0" and "__IPHONE_9_2" so it was an exact match for my devices' iOS and still nothing. Thoughts? – TJ Rogers Feb 02 '16 at 20:28
  • Doing a little research it seems Swift took away a lot of preprocessor code from Objective-C. Now it's limited to checking build (e.g., iOS, WatchOS, OS X, etc). But can't do versioning. Anyone have any other ideas? – TJ Rogers Feb 02 '16 at 22:08