Switch between different view controllers using swift - ios

I want to switch between different view controllers, here is my codes,
let sb = UIStoryboard(name:"Main", bundle: nil)
let vc = sb.instantiateViewControllerWithIdentifier("tabBarController") as ViewController
self.presentViewController(vc, animated: true, completion: nil)
'tabBarController' is the storyboad ID I had wrote in the identifier inspector.but I got some error at this line.
let vc = sb.instantiateViewControllerWithIdentifier("tabBarController") as ViewController
and here is the screenshot,
What's the problem?
And I have another question, here is the screenshot after the sb was initialized, the storyboardFileName is "Main.storyboardc", shouldn't it be "Main.storyboard"?
Thanks very much!!!!

The error is saying that the view controller returned by instantiateViewControllerWithIdentifier cannot be cast to a ViewController.
This is probably because you did not set the Custom Class property of your view controller in the storyboard to ViewController.
Go to your storyboard, select your view controller, then open the Identity inspector and look for the Custom Class property. Set it to ViewController and tab out of the field to make sure it takes. Then run again.

Related

Swift 4, load next ViewController

In my app I have two View Controllers embedded in Navigation Controller. And I want to have an option to get data from the SecondVC while only the FirstVC is opened. So it's like I don't want a user to see (or at least interact) with the SecondVC.
The point is
So user just taps on the button on the FirstVC (without opening SecondVC before) and I can get access to the data on the SecondVC.
How can I get data from the next view controller (SecondVC) in a navigation controller without opening it? Or at least not letting user to interact with it.
For now my only ideas are:
To push segue when user taps a button, get it into memory, load data and then dismiss it. But that doesn't look good when view controllers change so fast.
To present next view controller modally offscreen, get data and dismiss it. So the user won't even see that another view controller opened.
Edit:
I need to get access not just to method or smth. I need to get to the #IBOutlet. To the subclass of UIView (working with CorePlot) to be exactly
You should never call loadView() directly.
Instantiate your UIViewController and then call loadViewIfNeeded().
Calling this method loads the view controller’s view from its storyboard file, or creates the view as needed based on the established rules.
EDIT:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// make sure that the value is an optional so that you can unset it later. This one is optional because we use optional casting (with as?)
var vc = storyboard.instantiateViewController(withIdentifier: "secondVC") as? SecondViewController
vc?.loadViewIfNeeded()
// use the vc
// later unset vc variable
vc = nil
for this, you must call your 2ed View controller with 'modalPresent' and background of 2edVC must clear. Then get your data from 2ed VC. with no change. for more information about modalPresent there is the link.
Solution:
You can create a function for it or just insert in viewDidLoad() etc.
Don't forget to change StoryboardID for the chosen view controller (it can be done in your storyboard file in Identity inspector).
// You need to get to your Storyboard and instantiate the needed View Controller
let storyboard = UIStoryboard(name: "Main", bundle: nil)
var graphVC = storyboard.instantiateViewController(withIdentifier: "graphVCID") as? graphVC
// Then call loadViewIfNeeded (don't call loadView()) to load #IBOutlet's etc
graphVC?.loadViewIfNeeded()
// My outlets are loaded with data when these functions are called
graphVC?.viewDidLoad()
graphVC?.viewWillAppear(false)
// Unset the reference to VC
graphVC = nil

How can I call a view controller in swift 2 at the code?

I searched for similar problems, but none solved my problem. I need to call a new view controller , but when I do it a black screen appears , as I do to associate with the main storyboard screen?
Here is my suggestion:
let vc = storyboard!.instantiateViewControllerWithIdentifier("viewIdentifier") as! viewNeedToCall
You can init and use vc with navigation.
A black screen appears when the simulator can't figure what to present. It seems lost in the sense which controller it has to present.
If it is the first screen then make sure that you have set the initial view controller in Main.storyboard. If not, then you have to call(instantiate) that view controller using the instantiateViewControllerWithIdentifier property of a storyboard.
For e.g.If you want to present a ViewController named as YourViewController then
Make an object of YourViewController, say yourVCObject.
let yourVCObject = self.storyboard?.instantiateViewControllerWithIdentifier("YourViewController") as? YourViewController
Present your desired ViewController with -
self.presentViewController(yourVCObj!, animated: true, completion: nil)
Here connect your class YourViewController in the Identity Inspector in the "Class" and type "YourViewController" in the Storyboard ID and check the "Use Storyboard ID"
Looks like you forgot to connect your VCs to a NAVIGATION CONTROLLER.
Without Navigation controller you cannot move to another VC.

Swift Prepare for segue interrupted by TabBarController

I currently have a storyboard that has a tableview with my data, and I believe I correctly pass that data using the didSelectRowAtIndexPath and the prepareForSegue functions.My problem is that when I select a certain cell my cast becomes incorrect because I have a tab bar controller holding my views to be displayed with this segued information.I want my cast to be:
let destination = segue.destinationViewController as! DownloadViewController
But I am getting an error because the segue is going to the tab bar controller first. This error makes perfect sense to me but I am unsure how to get around it without getting rid of the tab bar controller completely. Here is a picture of my story board to help show the overall flow.
http://imgur.com/7gFKKIZ
Any help is appreciated.
The UITabBarController has an array that contains its connnected viewController, to access e.g. the first one try
let destination = (segue.destinationViewController as! UITabBarController).viewControllers?.first as! DownloadViewController
Instead of using segue, you can use a modal presentation of your desired first tab for display if it works for you.
let displayFirstVC = storyboard.instantiateViewControllerWithIdentifier("newVC") as! UIViewController
self.presentViewController(displayFirstVC , animated: true, completion: nil)
When you instantiateViewControllerWithIdentifier, you have to create a storyboard name for your FirstViewController with name newVC.
You would also need to replace UIViewController with the name you gave your view controller.
More details here.
Instantiate and Present a viewController in Swift

SetViewControllers with uiPageViewControllers is not working

I am making an app that uses a UIPageViewController for navigation between pages. Everything works fine except that when I am trying to manually change which view controller is shown using setViewControllers it does not show.
I know that it is creating the view controller because it prints to the log, but the controller shown on screen isn't changed. The indexes I use for the subclass of uiviewcontroller that makes each view controller are also set correctly.
The function is called on the press of a view controller.
Here's the code that is supposed to change the controller:
func changeVC(VC: UIViewController) {
setViewControllers([VC], direction: .Forward, animated: true, completion: nil)
}
And the function call:
Let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("contentView") as! ViewController
Controller.index = row
PageViewController().changeVC(controller)
That is inside of the didSelectRowAtIndexPath method of a table view.
Cjay was absolutely correct,
Lemme explain it little more in detail to help you understand what mistake you are doing.
Everytime you call PageViewController().changeVC(controller) new instance of PageViewController will be created and changeVC will be called on that new instance that you have just created. Though your code to instantiate a ViewController from storyboard setting it's index,calling changeVC and setting theViewController of PageViewController everything executes you won't see any of this making any effect on your screen because you changed the ViewController of the PageViewController which you just instiated which neither has a visible valid frame (0,0,0,0) nor it is loaded (not added to your ViewController's view) :)
Rather what you should have done is to do exact same things on a PageViewController which is already loaded :)
As per you comments you are loading the PageViewController from storyboard create an IBOutlet for it lets call it as myPageViewController :) so when you want to change the ViewController of it simply say,
let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("contentView") as! ViewController
controller.index = row
self.myPageViewController.changeVC(controller)
Hope this helps :)

How To addSubViews To Storyboard, Then Displaying It Using A Segue

I have a view controller reference to a storyboard of a given identifier. I'm adding a bunch of buttons to it, then trying to display it via a segue.
My problem is that when the segue fires, it creates a difference instance of the view controller with the same segue identifier, and thus it's blank.
What's the best practice to addSubView() to a storyboard, then getting that SAME storyboard object to display?
CLARIFICATION
Here's the flow I'm using:
Central VC -> Create SubVC using centralized Storyboard Object -> Adding SubViews to that SubVC in a factory class -> Queue Segue from SubVC back to the Central VC for segue using its identifier -> [it creates a NEW VC without my additions]
If you're using segues, then the Storyboard creates the destination viewController. If you want to customize the destination viewController, then you do that in prepareForSegue.
You can instantiate a view by code, and pushing in to you navigation controller, it's a clean approach and dont mess the Storyboard with unnecessary segues.
Just instantiate the next view (you must first give this view an StoryBoard ID), call it by code, and push it in the navigation controller.
Objective-C
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"storyBoard_Name" bundle:nil];
UIViewController* controller = [storyboard instantiateViewControllerWithIdentifier:#"ViewController_ID"];
[self.navigationController pushViewController:viewControllerName animated:YES];
Swift
let storyboard = UIStoryboard(name: "storyBoard_Name", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("ViewController_ID") as! UIViewController
self.presentViewController(vc, animated: true, completion: nil)

Resources