简体   繁体   中英

ios - IBOutlet class init not called and members are nil

I am trying to add search capabilities to the map based project I am working on in swift on XCode 6. I have added SearchDisplayController to my main view controller, which contains the map. I created a class called MapSearchDisplayController, which implements necessary methods. I also changed Custom Class property of the SearchDisplayController to MapSearchDisplayController in the storyboard.

In the storyboard, I dragged SearchDisplayController to my main view controller to create an IBOutlet. My main viewDidLoad for the main view controller looks like this:

class ViewController: UIViewController, CCHMapClusterControllerDelegate, MKMapViewDelegate, ADBannerViewDelegate {

    @IBOutlet weak var mapSearchDisplayController1: MapSearchDisplayController!
    @IBOutlet var mapSearchDisplayController: MapSearchDisplayController!
    @IBOutlet weak var banner: ADBannerView!
    @IBOutlet weak var mMap: MKMapView!
    var clusterController:CCHMapClusterController?
    let mMaxZoomLevelForClustering : Double = 13
    let mMinUniqueLocationsForClustering : UInt = 1
    var formatter = NSNumberFormatter()

    var databasePath = NSString()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        banner.delegate = self

        // Add button to navbar
        var filterButton : UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Organize, target: self, action: nil)
        self.navigationItem.leftBarButtonItem = filterButton

        var aboutButton : UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Add, target: self, action: "aboutAction")
        var searchButton : UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Search, target: self, action: "searchAction")
        var rButtons : [UIBarButtonItem] = [aboutButton, searchButton]
        self.navigationItem.rightBarButtonItems = rButtons


        // Deal with Search Display Controller
        self.mapSearchDisplayController.delegate = self.mapSearchDisplayController;
        self.mapSearchDisplayController.searchResultsDataSource = self.mapSearchDisplayController;
        self.mapSearchDisplayController.searchResultsDelegate = self.mapSearchDisplayController;
        self.mapSearchDisplayController.searchBar.placeholder = "Search Destination";
        self.mapSearchDisplayController.searchResultsTableView.delegate = self.mapSearchDisplayController
        self.mapSearchDisplayController.searchResultsTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")

Issue 1: I had to add an additional mapSearchDisplayController 1 - otherwise my mapSearchDisplayController was nil and I had an exception when I tried to to use it. Now when I have an additional variable mapSearchDisplayController 1 (it is declared, but never used) it is not throwing exceptions and some functionality is working. Tried to add/remove weak , bt it did not make any difference. I can't figure out what have I missed that leads to this behavior.

Isse 2: Even bigger problem that I have, is that the instance variables of mapSearchDisplayController, which handles the search related functionality, are nil, its init method is not being invoked, but the functionality in the delegate methods work. So, data1 variable is nil, despite being initialized to hardcoded string array. Same goes for all other members, including googleAPIKey which is a constant. If shouldReloadTableForSearchString set data1 again data1 = ["1111", "222", "ZAAAA"] then it remains initialized, but if I assign data1 the value I get as a searchresult - it is lost. I would understand if the entire object was nil, but the methods are being invoked and working, it is just an instance variables and init which are not "working". Code below:

class MapSearchDisplayController: UISearchDisplayController, UISearchDisplayDelegate, UITableViewDataSource, UITableViewDelegate, LPGoogleFunctionsDelegate
{
    var data1 : [String]! = ["1111", "222", "ZAAAA"]
    var googleFunctions : LPGoogleFunctions? = LPGoogleFunctions()
    let googleAPIKey = "myKey"
    //MARK: UITableViewDelegate

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        println("In numberOfRowsInSection - \(data1.count)")
        return self.data1.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        println("In cellForRowAtIndexPath")
        var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as? UITableViewCell
        if !(cell != nil) {
            println("new cellForRow")
            cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
        }
        // Get the corresponding candy from our candies array
        let candy = self.data1[indexPath.row]

        // Configure the cell
        cell!.textLabel.text = candy
        cell!.detailTextLabel?.text = "Cell Details"
        return cell!
    }   

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        // Dismiss search display controller
        self.active = false;

        // Force selected annotation to be on map
    }


    func tableView(tableView: UITableView, numberOfSectionsInTableView indexPath: NSIndexPath) -> Int{
        println("numberOfSectionsInTableView")
        return 1
    }

    //MARK: Search methods
    func filterContentForSearchText (searchText: String) {
        println(searchText)
    }

    func searchDisplayController(controller: UISearchDisplayController!, shouldReloadTableForSearchString searchString: String!) -> Bool {
        var  length : Int32 = Int32(countElements(searchString))
        if (countElements(searchString) < 3 ) {
            println("Short searchString. Not enough info")
            return false
        }
        data1 = []
        if (googleFunctions == nil)
        {
            googleFunctions = LPGoogleFunctions()
            googleFunctions!.sensor = false
            googleFunctions!.delegate = self
            googleFunctions!.googleAPIBrowserKey = "myKey"
        }
        println(googleFunctions?.googleAPIBrowserKey)
        googleFunctions?.loadPlacesAutocompleteWithDetailsForInput(searchString, offset: length, radius: 0, location: nil, placeType: LPGooglePlaceTypeGeocode, countryRestriction: nil, successfulBlock: {(pd : [AnyObject]!) in
            println("--------------GOOGLE search success")

            for place in pd{
                var pl = place as LPPlaceDetails
                self.data1.append(pl.name)
                println(pl.name)
            }
            }
            , failureBlock: {(status : LPGoogleStatus) in
            println("---- GOOGLE failed")
            })
        //data1 = ["1111", "222", "ZAAAA"]
        return true
    }

    func searchDisplayControllerWillBeginSearch(controller: UISearchDisplayController!){
        controller.searchBar.showsCancelButton = true
    }

    func searchDisplayControllerWillEndSearch(controller: UISearchDisplayController!){
        println("searchDisplayControllerWillEndSearch")
    }

    //MARK: LPGogleFunctions methods
    override init() {

        println("Initializing GoogleFunctions")
        if (googleFunctions == nil){
            googleFunctions = LPGoogleFunctions()
        }
        data1 = []
        super.init()

        googleFunctions!.sensor = false
        googleFunctions!.delegate = self
        googleFunctions!.googleAPIBrowserKey = "myKey"
    }
}

Any help would be greatly appreciated.

I am answering my own question, in case someone ever has the same problem.

Issue #1 I resolved by deleteing both IBOutlets and re-adding them in the storyboard.

Issued #2: I did not made a call to searchResultsTableView.reloadData(). Since the network call was async, results were received in the lambda after the tableview was updated. Forcing an update sovled the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM