I am trying to Compile my app again now that Swift 2 is out and the thing is I am having an error with TabBarController instances.
I am declaring the instances in vars in order to use methods from anothers ViewControllers.
Here it's my code:
let barViewControllers = self.tabBarController?.viewControllers
let listViewController = barViewControllers![2].viewControllers![0] as! dbViewController //The [2] is because it's the third TabBar and the [0] it's because It's embebed in a NavigationController.
let calendarViewController = barViewControllers![1] as! CalendarViewController
In the second line Im having the following error:
UIViewController does not have a member named "viewControllers"
Anybody could help me?
Thanks
You are trying to access the property viewControllers of the type UIViewController, which it doesn't have. viewControllers is a property on a UITabBarController, but viewControllers returns an array of UIViewController.
Cast viewControllers to an array of UITabBarController (or only the item you extract) to access it's viewController property.
Like this:
let barViewControllers = self.tabBarController?.viewControllers as! [UITabBarController]
Or this:
let listViewController = (barViewControllers![2] as! UITabBarController).viewControllers![0] as! dbViewController
Related
Storyboard screenshot with description
I've used this line of code in the UIViewController class of 2nd tab to access the tabBarViewController. But it crashes.
let friendView = self.tabBarController?.viewControllers![2] as! AccountTableViewController
Note: AccountTableViewController is the name of UITableViewController class of 3rd tab.
Thanks for your help.
Change your code like this
let navController = self.tabBarController?.viewControllers![2] as! UINavigationController
for vc in (self.navigationController?.viewControllers)! {
if (vc.isKindOfClass(AccountTableViewController.classForCoder())) {
let friendView = vc as! AccountTableViewController
}
}
I want to pass data from one view controller to another. And I am using the following code in the prepareForSegue to do so...
let detailVC: DetailVC = segue.destinationViewController as! DetailVC
detailVC.alertDict = sender as! NSDictionary
In the first line as you can see there is a ! after the as. Thats because I have to use it to force downcast, and if I do not include the ! then I get an error: UIViewController is not convertable to DetailVC. But DetailVC is a inheritance of UIViewController class, so why can it not convert? Here is the code for the class..
class DetailVC: UIViewController, MFMailComposeViewControllerDelegate, MFMessageComposeViewControllerDelegate {/*code*/}
Think of it like this.
All DetailVCs are UIViewControllers, but not all UIViewControllers are DetailVCs.
Therefore, while you can freely convert a DetailVC to a UIViewController such as:
let detailVC = DetailVC()
let vc : UIViewController = detailVC as UIViewController
You cannot do the reverse, as the view controller might not be a DetailVC.
Therefore you can use as! in order to force the cast to the DetailVC.
let vc : UIViewController = DetailVC()
let detailVC = vc as! DetailVC
If it's a DetailVC, then it'll convert no problem; if it isn't, it will crash.
If you're not 100% sure of the type before you cast, you should always use as? in order to check the type before converting. For example:
let vc : UIViewController = DetailVC()
if let detailVC = vc as? DetailVC {
// do something
}
Or, as user965972 says, you can go one step further by using a guard statement to prevent any further execution if the casting fails. For example:
let vc : UIViewController = DetailVC()
guard let detailVC = vc as? DetailVC else {
// uh oh, casting failed. maybe do some error handling.
return
}
// freely use detailVC from the this point onwards, with the correct type.
The method you use depends entirely on if you want to handle errors and whether further execution depends on the casting being successful.
I assume you are getting a runtime error.
Make sure your view controller is set to the correct class in interface builder. If you first set the class in IB and then define the class in your code, IB will not find the class. You will notice this by looking at the "module" field under the "class" field in IB. It should not be "None", but something like the name of your project.
I have an Swift app (xCode 7.1). I need send a value from a first viewController that contains a tableView to the two viewControllers into a TabBar Controller:
ViewController -> Tabbar -{ViewControllerTabBarView1
-{ViewControllerTabBarView2
I call the tabBar controller from didSelectRowAtIndexPath
let vc : AnyObject! = self.storyboard!.instantiateViewControllerWithIdentifier("myTab")
self.showViewController(vc as! UIViewController, sender: vc)
All this is correct, but the values to pass from click into row to respective viewController of TabBar not work calling from didSelectRowAtIndexPath. This is null
let viewController = self.storyboard!.instantiateViewControllerWithIdentifier("view1TabBar") as! EventoToDoController
viewController.finca = (parsed.valueForKey("id")[indexPath.row] as? String)!
How can I send this values?
I have a root UIViewController that has its NSManagedObjectContext var set by AppDelegate (iOS8 app coded using Swift).
The root controller(the master view of a splitview controller) has a button whose action presents another UIViewController with the following code segment:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("addGeometricEntityContent") as! UIViewController
vc.managedObjectContext = self.managedObjectContext
self.presentViewController(vc, animated: true, completion: nil)
I get a compiler error as follows:
'UIViewController' does not have a member named 'managedObjectContext' for the line of code:
vc.managedObjectContext = self.managedObjectContextas a test
I tried adding a simple testPrint() function to the presented UIView Controller as a test and got a similar complaint that vc instance does have a method testPrint()
Is the vc instance created by storyboard.instantiateViewControllerWithIdentifier somehow different from a fully instantiated object?
If I remove the line
vc.managedObjectContext = self.managedObjectContext
the code works as expected and presents the UIViewController instance.
The application delegate object is accessible from everywhere, so you could write in your view controller
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedObjectContext = appDelegate.managedObjectContext
I was able to correct the problem by down casting the UIViewController type to my specific controller type as follows:
let vc = storyboard.instantiateViewControllerWithIdentifier("addGeometricEntityContent") as! AddGeometricEntityContentViewController
I have a standard SplitViewController app in Swift in Xcode 6.1.1. It would be very convenient for my DetailViewController have a pointer to my MasterViewController. (I don't need to send notifications, but I need to pull the current statemachine from my MVC)
My thought was that I would use my DetailViewController viewDidLoad method to grab the MasterViewController from the SplitViewController.
In my DetailViewController:viewDidLoad I have
(snip)
let tVC = self.splitViewController?.viewControllers[0] as? UIViewController
let tNav = self.splitViewController?.viewControllers[0] as? UINavigationController
let tMVC = self.splitViewController?.viewControllers[0] as? MasterViewController
When I inspect these, my tVC and tNav variables were successfully set, but my tMVC was nil. I thought that the splitViewController.viewController[0] would give me my MasterViewController directly, but I'm getting a UINavigationController instead.
Am I wrong/is there a better way to do this?
Found it.
let tNav = self.splitViewController?.viewControllers[0] as? UINavigationController
if let tMVC = tNav?.topViewController as? MasterViewController {
masterViewController = tMVC
stateMachine = tMVC.stateMachine
}