Using Storyboard Reference - ios

How to use Storyboard reference to connect 2 storyboards? Is it possible to connect storyboard with xib file? I want to use it via Navigation Controller.

if you want to reference two storyboards in Xcode 7, in your initial storyboard select the view controllers you want to use in the second storyboard, in the task bar select "Editor" and then "Refactor to Storyboard", then you have to name the new storyboard and thats all, i don´t know if you can reference to an .xib file, notice that you can use the storyboard reference to call a view even in the same storyboard or even a view that is not connected to any other view, and in the reference you can specify which view you want to load (you do this in the identity inspector), or leave that space empty and the view loaded will be the initial view.
Better explained step by step:
If you want to create the new storyboard at the same time
select the views you want to move to the new storyboard
open the Editor's menu and select Refactor to Storyboard
Xcode will ask you the name you want to give to the new storyboard
and thats all
If you have already created the storyboard
Open the storyboard where you want to call the second storyboard
drag the Storyboard Reference that is located in the objects library
select the reference you added and open the identity inspector
in the identity inspector write the name of the storyboard that you want
to call (required) and the storyboardID of the view you want to load
(optional)
thats how you use storyboard references in Xcode 7, hope that is useful to you

You can load another storyboard simply like this your main storyboard..just replace the name of storyboard and viewcontroller
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"NewStoryboard" bundle: nil];
SomeViewController *someViewController = [storyboard instantiateViewControllerWithIdentifier:#"SomeViewController"];
[self presentViewController:someViewController animated:YES completion:nil];
or Swift
let storyboard = UIStoryboard(name: "NewStoryboard", bundle: nil)
let someViewController = storyboard.instantiateViewControllerWithIdentifier("SomeViewController") as! UIViewController
self.presentViewController(someViewController, animated: true, completion: nil)

Hi Friend this is really easy,
Just create a new Storyboard with file>newfile and get the new Storyboard from User Interface don't forget to name it properly ;)
Drag a Storyboard reference to your main story board and now connect it with button or navigation bar button or tab bar whatever (as per your requirement)and thats it...
Select Storyboard reference and go to Attribute Inspector you can see the dropdown of story board from that select your new Storyboard.
Create any new view controller in the empty Storyboard and make it initial view controller.
Run the code
This is how you do it my friend hope it helps :)
Tell me if you are not able to solve will update my answers with screen shots.

Related

Do we need a Storyboard ID in iOS Xcode

I am setting up a basic iOS app and saw the Storyboard ID section of the Identity Inspector (as well as the Use Storyboard ID checkbox) and was curious as to whether this is actually something I need to create an app. If so what do I need to set this field to given the use below:
More specifically I am setting up 2 simple views and 2 corresponding viewcontrollers in my app. I was just trying to create a simple button to go from the first view to the second view and was using this method for the button which would ultimately transition from the first view to the second view once it was pressed:
let vc = self.storyboard?.instantiateInitialViewController(withIdentifier: "SecondViewControllerID") as! TransitionViewController
The view controller for the second view I want to be the destination of the button is named TransitionViewController. I borrowed this code from some samples and "SecondViewControllerID" is the name of the storyboard from the sample I'm borrowing from. In my Xcode, the Storyboard ID field is blank at the moment.
You need to set the storyboard id to SecondViewControllerID or ctrl-drag from the button to the destination vc through segue
Explanation :
Storyboard identifier is a unique key set for a vc inside storyboard to identify it when you load with instantiateInitialViewController
Regarding segue : CTrl-drag from the button to destination and from the popup select show
and don't write any code inside button action
The storyboard id ia mainly used when you have more than one StoryBorad.
if you have 2 storyborads you can initialize the vc by using
var vc = UIStoryboard(name: "main", bundle:nil).instantiateInitialViewController(withIdentifier: "SecondViewControllerID") as! TransitionViewController
and give "SecondViewControllerID" in Storyboard ID section of the TransitionViewController Identity Inspector.

One segue to rule them all

I have 4 ViewControllers in my storyboard. I want all of them to be able to access my "Settings" ViewController by performSegue.
Is it possible to have ONE segue to perform this, instead of ctrl + drag from each and every ViewController to my "Settings" ViewController?
No its not possible with a single segue. You need 4 different segues from 4 different ViewControllers. But you can do this programatically.
Make an extension for UIVIewController
extension UIViewController
{
func showSettingsScreen()
{
let storyBoard = UIStoryboard(name: "YourStoryBoardName", bundle:nil)
let settingsScreen = storyBoard.instantiateViewControllerWithIdentifier("YourSettingsViewControllerID")
self.navigationController?.pushViewController(settingsScreen, animated: true)
}
}
Now you can call showSettingsScreen() from any of your view controllers(Make sure this view controller has a navigation controller).
You cannot do that. A segue has only one source and one destination. You could programatically instantiate your Settings ViewController and display it either by using push or by using present. What you should think of though is why do you have to go to settings from so many places. It might be a sign of bad design and duplicate code. Usually applications have only one such button/action that can be accessed from multiple screens (by using some kind of container view implementation) or from only one screen.
I really dont think so there is a way to do so. U ought to connect ur SettingsViewController to all of your 4 View Controllers, add segue , and define a segue identifier which is used in
prepareForSegue:sender:
or
shouldPerformSegueWithIdentifier:sender:
methods. U can access segues through these identifiers. If u find "ctrl + drag from each and every ViewController to "Settings" ViewController " tasky you can opt for Navigation Controller as well. U just have to embed Navigation Controller in your storyboard and define Storyboard Id for every View Controller and you are done. Just use storyboard id of view controller to be instantiated and u good to go.
ViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
[self.navigationController pushViewController:vc animated:YES];
Apart for assigning storyboard id you dont have to worry about storyboard ,No ctrl+drag thing.
I thought of one more elegant solution i.e. using Container View. You can take button to switch, SettingsViewController as common, in your Container View Controller while displaying every ViewController.
happy Coding..
There is one way to do this. Create a root view controller and matching view which contains a single embedded view. Add your segue to this root controller. Then in your app you switch in the other view controllers using standard child container techniques. This is pretty much the concept that UINavigationControllers use.
One advantage from this is that if you want to have common elements which are visible to all controllers then you can add them to your root controller.
But it all depends on what you are trying to achieve.

Storyboard doesn't contain a view controller with identifier ... when using multiple storyboard files

I used to have all my view controllers in the same storyboard, I decided that makes sense to split up the storyboards so I created a new storyboard file New File -> User Interface -> StoryBoard, cut all the controllers related with the user management (Login, register, password recover ...) and pasted them in the new file
Now when I call storyboard.instantiateViewControllerWithIdentifier("LoginViewController") it crashes with the following error:
'Storyboard (<UIStoryboard: 0x...>) doesn't contain a view
controller with identifier 'LoginViewController''
How can I solve that?
I think your problem is here, navigate to the Main.storyBoard after that click on your viewController which you want to initiate after that give it to the identifier here:
May be this will help you.
You have to create the new storyboard instance, and get the LoginViewController StoryboardId
//Here, create an instance of the second storyboard excluding the extension(.storyboard),
var storyBoard = UIStoryboard(name: "SecondStoryBoard", bundle: nil)
//Here instantiate view controller with the storyboard instance,
//Before that create a storyboardId for the corresponding view controller.
var loginVC = storyBoard.instantiateViewControllerWithIdentifier("loginViewController") as LoginViewController
//Here, the storyboard identifier is "loginViewController" which is created in the respective view controller's "Identity" inspector
Hope this helps, Happy Coding :)

My app requires using instantiateViewControllerWithIdentifier - why?

I have added a Storyboard file to an app that initially had none. For some reason, I could not get my custom UIViewController to display correctly until I added this into didFinishLaunchingWithOptions:
ActivityViewController *viewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:NULL] instantiateViewControllerWithIdentifier:#"ActivityViewController"];
Why do I need to force the use of my storyboard like this? The iOS template projects (Single View, Master-Detail etc) doesn't need this.
Checklist:
Xcode Project Summary→Main Storyboard is set correctly to "MainStoryboard".
Interface Builder→Identity Inspector→Class is correctly set to "ActivityViewController".
Interface Builder→Identity Inspector→Storyboard ID is also set to "ActivityViewController", but this is only because it's needed by instantiateViewControllerWithIdentifier.
You do not need to call instantiateViewControllerWithIdentifier if you set Is Initial View Controller on your "ActivetyViewController" in the storyboard. The initial view controller will have an arrow pointing at it.

Storyboard doesn't contain a view controller with identifier

I keep getting the following error:
Storyboard (<UIStoryboard: 0x7ebdd20>) doesn't contain a view controller with identifier 'drivingDetails'
This is the code:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"drivingDetails"];
controller.title = [[dao libraryItemAtIndex:indexPath.row] valueForKey:#"name"];
[self.navigationController pushViewController:controller animated:YES];
}
I have already set the identifier on the UIStoryboard but I'm still getting this error.
Just for future reference:
I'm developing on iOS 6 using Storyboards.
I was having the same issue, but I could not find the "Identifier" field in the inspector.
Instead, just set the field named "Storyboard ID" to what you would name the Identifier. This field can be found under the "Show the Identity inspector" tab in the inspector.
[Note - comments below indicate that some people have found that they need to (also?) set the field "Restoration ID" just below the Storyboard ID in the inspector. Clicking on "Use Storyboard ID" does not seem to be enough.]
There's an image below for reference: (in this instance I've named my identifier the same as my class)
In Xcode 7 - 13,
when you change storyboard IDs and you get errors like this,
just CLEAN your project (CMD+SHIFT+K)
let storyboard = UIStoryboard(name: "StoryboardFileName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "StoryboardID")
self.present(controller, animated: true, completion: nil)
Note:
"StoryboardFileName" is the filename of the Storyboard and not the ID of the storyboard!
"StoryboardID" is the ID you have manually set in the identity inspector for that storyboard (see screenshot below).
Sometimes people believe that the first one is the Storyboard ID and the second one the View Controller class name, so note the difference.
Fixed! Not only the identifier in the segue must be set, in my case DrivingDetails, but also the identifier in my tableViewController must be set as DrivingDetails...check my picture:
I also removed the navigation view controller so now the 2 table view controllers are connected directly with a "push" animation.
*****EDIT for XCODE 7.0*****
you have to set the storyboardId(in this case the viewController is embedded in a Navigation controller:
let lastMinVc = mainStoryBoard.instantiateViewControllerWithIdentifier("lastMinuteNavController") as! UINavigationController
Identity located in Identity Inspector tab named Storyboard ID for Xcode 6.3.2 and checked Use Storyboard ID option.
Just had this issue after adding a new VC to the storyboard but only on the device, not on the simulator. Turns out it was due to having multiple storyboard localizations - the VC was only added to the primary one. I tried removing the other localizations (one of which is the one my iPhone uses) but still had the error. In the end I had to recreate the other localizations with the new VC in each of them.
Compiler shows following error :
Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: 'Storyboard (<UIStoryboard: 0x7fedf2d5c9a0>) doesn't contain a
ViewController with identifier 'SBAddEmployeeVC''
Here the object of the storyboard created is not the main storyboard which contains our ViewControllers. As storyboard file on which we work is named as
Main.storyboard. So we need to have reference of object of the Main.storyboard.
Use following code for that :
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
Here storyboardWithName is the name of the storyboard file we are working with and bundle specifies the bundle in which our storyboard is (i.e. mainBundle).
For those with the same issue as #Ravi Bhanushali, here is a Swift 4 solution:
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
I found it ...
click on the view controller in storyboard,
click the third icon from left on the vc attributes inspectors - the one where you set the call name
on that scereen it says 'identity' - mine was hidden , i had to click on the word identity
it then shows storyboardID - add the identifier from the code, done
Modifying "Storyboard ID" in the identity inspector (the 3rd icon to the left) should work.
If not and you're sure there's no typo, try cleaning up the project ("Product"->"Clean", or simply command + shift + K).
While entering the identifier u have not selected proper view controller, just check once if done repeat the procedure once more.
A few of my view controllers were missing the storyboardIdentifier attribute.
Before:
<viewController
id="pka-il-u5E"
customClass="YourViewControllerName"
customModule="ModuleName"
customModuleProvider="target"
sceneMemberID="viewController">
After:
<viewController
storyboardIdentifier="YourViewControllerName" <----
id="pka-il-u5E"
customClass="YourViewControllerName"
customModule="ModuleName"
customModuleProvider="target"
sceneMemberID="viewController">
I was facing the same issue. I had given the identifier but the compiler was giving the issue, so I made the new controller and gave that controller a new ID and added it and it's working perfectly! I have added pods as well but don't know why the error was coming but now its gone! Plus also try to clean your project by pressing CMD+SHIFT+K keys. Lemme know if it worked.
I got same error and I could fix this by changing the following changes in my project. I have mentioned my class name in the inspector panel then the problem is solved.
Goto->right panel there Identity Inspector
In the custom class section
class:your class name(ViewController)
In the Identity section
storyboard ID:your storyboard ID(viewController Name)
After this click on Use storyboard ID option over there.That's it the problem is finished. I hope it will help you....
Use your identifier(#"drivingDetails") as Storyboard ID.
it is very simple select the respective view controller in the main story board and check the storyboardID if its present use it in the identidier of give a name and use it.
here my firstone is the storyboardID
let vc = self.storyboard?.instantiateViewController(withIdentifier: "firstone") as! tabBarViewController
I tried all of the above solutions and none worked.
What I did was:
Project clean
Delete derived data
Restart Xcode
Re-enter the StoryboardID shown in previous answers (inside IB).
And then it worked. The shocking thing was that I had entered the Storyboar ID in interface builder and it got removed/deleted after opening Xcode again.
Hope this helps someone.
Cleaning all things and closing Xcode doesn't solved the issue for me.
I had to delete the viewController and create a new one with new identifier.
Note: If you use cocoapods in your project, then first run pod deintegrate and rm Podfile.lock
Then open your project folder in any third party code editor like VSCode and do a global search for the ViewController name throwing the error.
Rename/fix any wrong names which you find.
Save all changes.
Clean and build your project.
Everything should work fine now.
This is most often caused when you rename files from within Xcode.
check your language, may be the (base) have your controller, but may be specific storyboard does not have it
XCODE DRAG N DROP PANE IS GONE!!!

Resources