My app requires using instantiateViewControllerWithIdentifier - why? - ios

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.

Related

Navigate between multiple storyboards in iOS App

I wanted to have separate storyboard files for every UIViewcontrollers in my iOS app.
So how can we assign different storyboards for each controllers? Also how do we do navigation between those?
This I am doing to avoid svn conflicts while so many people working on UI.
get a reference to the storyboard...
UIStoryboard *someStoryboard = [UIStoryboard storyboardWithName:#"NameOfYourStoryboard" bundle:nil];
then instantiate either the initial viewcontroller from that storyboard...
UIViewController *initialViewController = [someStoryboard instantiateInitialViewController];
or some other viewcontroller identified by it's storyboard identifier...
UIViewController *someOtherViewControllerFromTheStoryboard = [someStoryboard instantiateViewControllerWithIdentifier:#"SomeViewControllersStoryboardIdentifier"];
after that you can simply push (within a navigation controller) or present the new viewcontroller.
since iOS 9.0 you can even connect storyboards via storyboard references in the storyboard itself:
https://developer.apple.com/library/prerelease/ios/recipes/xcode_help-IB_storyboard/Chapters/AddSBReference.html
Keeping different storyboards for different modules is good approach. You can achieve the navigation between storyboards as follows:-
Suppose you are in A view controller and want to push another view controller named FabIdeaDetailViewController which is present in storyboard named FabIdeas:-
FabIdeaDetailViewController *horizontalListController = (FabIdeaDetailViewController*)[UIViewController instantiateViewControllerWithIdentifier:#"FabIdeaDetailViewController" fromStoryboard:#"FabIdeas"];
[self.navigationController pushViewController:horizontalListController animated:YES];
Now for pushing another view controller named WishlistViewController which is present in storyboard named Wishlist:-
UIViewController *WishlistViewController = [UIViewController instantiateViewControllerWithIdentifier:#"WishlistViewController" fromStoryboard:#"Wishlist"];
[self.navigationController pushViewController:WishlistViewController animated:YES];

access multiple viewControllers from the main viewControllers programmatically in a storyboard

first part of my question is basic understanding.
I believe the other viewControllers in the storyboard are in a "Non instantiated" form when application is launched, and are launched when they are sequed, please confirm?
Second part how do I programmatically instantiate a sibling UIViewController within the storyboard and optionally create a seque to it. I've found some code from Objective-C (pasting below) but looking for a solution in SWIFT.
MyViewController *myVC = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"MyViewController"];
Your first statement is true to a certain extent. Any controller connected to one that does get instantiated by a relationship segue or an embed segue will also be instantiated (like all the children of a tab bar controller). In your code snippet, you don't need to use storyboardWithName: if you're calling that method from a controller that was created in the same storyboard; you can just use self.storyboard.
var myVC = self.storyboard.instantiateViewControllerWithIdentifier("MyViewController")

Shows blank view when loading view controller from StoryBoard

I have a project which is already in App Store.
Now I need to add some more screens using storyboards to the project. The project was previously implemented using nib files.
I have created storyboard for the new view controller which I have added. When the view controller is called it comes up almost blank, none of the views which I have added for the controller are not showing up.
I have added below code how i'm loading the view controller from story board.
-(void)gotoEventsScreen
{
EventsListViewController* eventsScreen = [[UIStoryboard storyboardWithName:#"EventsScreen" bundle:nil] instantiateInitialViewController];
[self.navigationController pushViewController: eventsScreen animated:YES];
}
Note: I have made EventsListViewController as initialviewcontroller and it also has identifier.
I have also tried to load with identifier still it shows me the blank screen.
Actually there was some problem with my project base class view controller which consists the initWithCoder method which was not calling its super class method.

iOS Change Story Board

My iPad App has two storyBoards - FirstStoryBoard and SecondStoryBoard
I have a single ViewController
I notice that Under Project > Targets > Summary there is an option for specifying the MainStoryBoard and if I change this setting the correct story board loads correctly.
The Question - How can I change the behavior so that I can change between the first and second story board at run time. In other words I want to
First, create storyboard instance:
UIStoryboard *board = [UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil];
and then get first view controller from it:
UIViewController *vc = [board instantiateInitialViewController];
add as child view controller:
[self addChildViewController:vc];
or maybe (if you are in AppDelegate.m / application:didFinishLaunchingWithOptions: method)
self.window.rootViewController = vc;
The Question - How can I change the behavior so that I can change
between the first and second story board at run time.
You can't switch the value of the Main Storyboard setting (specified by the UIMainStoryBoard key in your Info.plist) at runtime, so do the next best thing: use a common storyboard or nib file that contains very little, and then instantiate the storyboard that you want using the UIStoryboard class. For example, you could use a simple nib file to create your app delegate, and have the app delegate's -application:willFinishLaunchingWithOptions: load first view controller from the storyboard of your choice.

Contained UIViewControllers - should I use .xib or the storyboard?

I'm making an app that will have a VC doing a similar job as a UITabBarController and I'm using
[self addChildViewController:theViewController];
// [self addSubview ... etc
to put a custom UIViewController's view as a subview of my main (root) VC.
So my question is, which is the correct way to instantiate a VC and not have to build it's UI programatically - from a .xib file, or from a storyboard?
With a xib:
UICustomViewController *controller = [[UICustomViewController alloc] initWithNibName:#"customVC" bundle:nil];
With a storyboard:
UICustomViewController* child = [self.storyboard instantiateViewControllerWithIdentifier:identifier];
I believe .xib files are old stuff and storyboards are the way to go, but I also read this article, which suggests that using a storyboard to do this is a bit hacky. I don't know, any thoughts?
there is nothing any major difference in both way , they are same . but in many other angle storyboard is the straight way, there is nothing any hacky
If you want the child view controller to be present when the app opens, you can do it in a storyboard without any code at all. Add a container view to your root vc, and you will automatically get a view controller embedded in it.

Resources