user3185748 user3185748 - 4 months ago 24
Swift Question

Swift - How to call method from a specific instance?

I am currently developing an iOS app using the CarbonKit library for navigation. I currently have a

UITableView
in the first tab, and I want to programatically navigate to another tab when a cell is selected.

I have implemented the following function under my main
CarbonKit
view controller:

import CarbonKit

class ViewController: UIViewController, CarbonTabSwipeNavigationDelegate {


func carbonTabSwipeNavigation(carbonTabSwipeNavigation: CarbonTabSwipeNavigation, viewControllerAtIndex index: UInt) -> UIViewController {

switch index {
case 0:
return self.storyboard!.instantiateViewControllerWithIdentifier("AircraftViewController") as! AircraftViewController
case 1:
return self.storyboard!.instantiateViewControllerWithIdentifier("LoadController") as! LoadController
case 3:
return self.storyboard!.instantiateViewControllerWithIdentifier("SettingsController") as! SettingsController
default:
return self.storyboard!.instantiateViewControllerWithIdentifier("ViewControllerOne") as! ViewControllerOne
}
}

func navigate(index: UInt) {
carbonTabSwipeNavigation.setCurrentTabIndex(index, withAnimation: true)
}

}


setCurrentTabIndex
is the function provided by the library to programatically switch tabs.

In my
UITableViewController
I have the following:

import UIKit
import CarbonKit

class SecondViewController: UITableViewController {

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

\\ First Attempt
(ViewController() as CarbonTabSwipeNavigationDelegate).navigate(2)

\\ Second Attempt
let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("controller") as! ViewController
viewController.navigate(2)
}

}


I understand that with my first attempt I created a new instance of
ViewController
and my second attempt didn't select the instance I was hoping for.

How can I best activate the method in the first instance of
ViewController
from
SecondViewController
?

Answer

Start by adding a CarbonTabSwipeNavigation property to your SecondViewController class, so you will have access to your navigation provider:

import UIKit
import CarbonKit

class SecondViewController: UITableViewController {
    var carbonNavigation : CarbonTabSwipeNavigation?;

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
       if let carbonNav = self.carbonNavigation {
           carbonNav.setCurrentTabIndex(index, withAnimation: true)
       }
   }

}

Next up we need to set that carbonNavigation property, so it will be available for use. It looks like your CarbonTabSwipeNavigationDelegate is a nice place to do that. On a side note, I don't see your SecondViewController ever being returned by your delegate - is that intended?

import CarbonKit

class ViewController: UIViewController, CarbonTabSwipeNavigationDelegate {


    func carbonTabSwipeNavigation(carbonTabSwipeNavigation: CarbonTabSwipeNavigation, viewControllerAtIndex index: UInt) -> UIViewController      {

        switch index {
        case 0:
            let aircraftVC = self.storyboard!.instantiateViewControllerWithIdentifier("AircraftViewController") as! AircraftViewController
            aircraftVC.carbonNavigation = carbonTabSwipeNavigation
            return aircraftVC
        case 1:
            // do something similar, instantiate view controller, set navigation property
            return self.storyboard!.instantiateViewControllerWithIdentifier("LoadController") as! LoadController
        case 3:
            // do something similar, instantiate view controller, set navigation property
            return self.storyboard!.instantiateViewControllerWithIdentifier("SettingsController") as! SettingsController
        default:
            // do something similar, instantiate view controller, set navigation property
            return self.storyboard!.instantiateViewControllerWithIdentifier("ViewControllerOne") as! ViewControllerOne
        }   
    }

    func navigate(index: UInt) {
        carbonTabSwipeNavigation.setCurrentTabIndex(index, withAnimation: true)  
    }
}

You could also add a ViewController property instead of a CarbonTabSwipeNavigation and expose all of the methods you need from Carbon as methods in ViewController. That would mean changing the type of the property declaration and setting it to self instead of carbonTabSwipeNavigation.

Comments