Initialize Swift storyboard from Objective-C - ios

I'm trying to add a new storyboard in Swift to an old Objective-C app:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard01" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"OnboardingViewController"];
[self presentViewController:vc animated:YES completion:NULL];
With Swift storyboard:
I'm always getting error:
'Could not find a storyboard named 'MainStoryboard01' in bundle NSBundle <.../Developer/CoreSimulator/Devices/753636C1-ABB5-4D6E-B184-5C4638FB2CE9/data/Containers/Bundle/Application/398410C0-BB2C-4574-B058-95D30F8D1B5D/Credit Call.app> (loaded)'
Calling swift classes like
TestClass *instance = [TestClass new];
[instance testFunction];
Normally works. Any idea how to call swift storyboard + it's swfit controller in Objective-C app?
// EDIT:
I finally get working this:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Onboarding" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"MainStoryboard01"];
but on next line
[self presentViewController:vc animated:YES completion:NULL];
I get this error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyAppDelegate presentViewController:animated:completion:]: unrecognized selector sent to instance 0x6080000b3b60'
Any ideas? I need to replace this with the storyboard:
Registration *reg = [[Registration alloc] init];
registrationNav = [[UINavigationController alloc] initWithRootViewController:reg];
[reg release];
[self.mainBackgroundView addSubview:[registrationNav view]];
=> https://codepaste.net/jkfras I've added skeleton of the MyAppDelegate.m

You are making mistake here, MainStoryboard01 that you have set is Storyboard Identifer using that you can called instantiateViewControllerWithIdentifier. It is not the another storyboard name. So its should be simply like this.
//You need to put storyboard name here the check the image for more detail
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"MainStoryboard01"];
[self presentViewController:vc animated:YES completion:nil];
Edit: Try this way.
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"MainStoryboard01"];
[self.mainBackgroundView addSubview:[vc view]];

If you want to reference to a storyboard then you should use its name, so if your storyboard has a name "MyNewStoryboard" (MyNewStoryboard.storyboard) then the right way to create its reference is like this:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MyNewStoryboard" bundle:nil];
Don't use a storyboard ID here. Storyboard ID you just set in the controller's attributes is the identifier for your controller. So you can use it this way:
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"MainStoryboard01"];
Change your new controller's Storyboard ID to something more informative, so for example "OnboardingViewController", and then after putting your storyboard file name in your first line your code should be fine.

Related

Programmatically load ViewController from Storyboard in app with multiple storyboards

I am working on an application that is transitioning to having multiple storyboards for different sections of the app. They are linked together by programmatically loading them at the appropriate times.
In a function for when a UIButton is tapped, it should programmatically load a storyboard. The code is like so:
- (void)loginTapped:(id)sender {
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Home.storyboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"homeStoryboard"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];
}
The storyboard is named the name listed in in the function:
and is listed as a target in the project settings appropriately:
and has the appropriate ID like so:
However, even after setting all this I get the error:
'NSInvalidArgumentException', reason: 'Could not find a storyboard named 'Home.storyboard' in bundle NSBundle
I have tried to follow the advice from this post here, but nothing has worked. How do I get this storyboard to load?
The solution (as mentioned in the comments above) is to not include the .storyboard when providing the name of the storyboard.
Old
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Home.storyboard" bundle:nil];
New
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Home" bundle:nil];
Try this:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Home" bundle:nil];
To call any ViewController programmatically in ios using Objective c:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:Home bundle:nil];
yourDestinationViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#homeStoryboard];
[self presentViewController:vc animated:YES completed:^{}];
yourDestinationViewController in the code is your view controller.h file.
You want to import that viewcontroller.h file in your program, where you want to call the View controller programmatically.
and to create the property like below,
#import "viewcontroller.h"
#property viewController *yourDestinationViewController;

iOS: Tab change programmatically - storyboard

I am trying to change tab programmatically in storyboard but getting error
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
TabViewController *tabBarCon = [storyboard
instantiateViewControllerWithIdentifier:#"tabBar"];
tabBarCon.selectedViewController = [tabBarCon.viewControllers objectAtIndex:1];
Error
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
Here tabBarCon.viewControllers is not empty.
NSLog(#"%#",tabBarCon.viewControllers); giving
(
"<FirstViewController: 0x16642020>",
"<SecondViewController: 0x173c4c00>",
"<ThirdViewController: 0x166db570>",
"<ForthViewController: 0x166d17c0>",
"<FifthViewController: 0x166066a0>"
)
You need to have instance of tabbarcontroller.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
TabViewController *tabBarCon = [storyboard instantiateViewControllerWithIdentifier:#"tabBar"];
This statement creates new instance of tabbar from storyboard.
[self.tabBarController setSelectedIndex:1];
If you are within the tab bar controller then you will easily get the instance using self.tabBarController
Try This:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
TabViewController *tabBarCon = [storyboard instantiateViewControllerWithIdentifier:#"tabBar"];
[self.tabBarController setSelectedIndex:1];
Try This
UITabBarController *controller =(UITabBarController *)
self.window.rootViewController;
[controller setSelectedIndex:1];
i have tried on Appdelegate it is working

UIStoryboard with object

I have multiple storyboards within my app. I want to pass an object when a new storyboard is opened.
I'am doing this:
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"SetupStoryboard" bundle:[NSBundle mainBundle]];
UINavigationController* initialHelpView = [storyboard instantiateInitialViewController];
SetupViewController *setup = (SetupViewController*) [initialHelpView topViewController];
setup.data = self.data;
initialHelpView.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:initialHelpView animated:YES completion:nil];
But when the storyboard is presented the setup.data is nil in viewDidLoad, viewWillAppear etc of the SetupViewController...
Why is that?
I don't see anything wrong with this code. Problem may be elsewhere.

Use initWithNibName with a storyboard

Below is an example of using initWithNibName with separate xib views:
TerminalViewController *ctrl = [[TerminalViewController alloc]
initWithNibName:#"ControllerView" bundle:[NSBundle mainBundle]];
ctrl.appDelegate = self;
viewCtrl = ctrl;
However i need to implement it with a storyboard UI layout. For 'initWithNibName' how can i point to a View in my storyboard:
i.e. :
TerminalViewController *ctrl = [[TerminalViewController alloc]
initWithNibName:#"STORYBOARD.ControllerView" bundle:[NSBundle mainBundle]];
ctrl.appDelegate = self;
Any help is much appreciated.
Thanks,
Dave
You can give the controller an Identifier in the storyboard and then use this...
[self.storyBoard instantiateViewControllerWithIdentifier:#"TheIdentifier"];
Just to add to this...
When creating a UIViewController subclass from a xib file. If you have a class called MyViewController and a xib called MyViewController.xib then all you need to do is...
MyViewController *controller = [[MyViewController alloc] init];
The system will then look for a xib file called MyViewController.xib and use that to init the object and only fallback to doing it in code if the xib file doesn't exist.
get storyboard instance with name of storyboard and set identifier to all scene and get the instance
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
MyNewViewController *myVC = (MyNewViewController *)[storyboard instantiateViewControllerWithIdentifier:#"myViewCont"];
UIStoryboard *stryBoard=[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
TerminalViewController *ctrl = [stryBoard instantiateViewControllerWithIdentifier:#"ControllerView"];

Passing managedObjectContext via presentViewController

I am trying the "pass the baton" method for passing the managedObjectContext (MOC) thru multiple views. I have it successfully passed to the rootViewController. From there I move to a tabBarController via presentViewController. I can't seem to find a way to pass the MOC when the tabBarController is pushed.
AppDelegate.m
UIViewController *navigationController = (UIViewController *)self.window.rootViewController;
MyViewController *controller = (MyViewController *) navigationController;
controller.managedObjectContext = managedObjectStore.mainQueueManagedObjectContext;
The main view controller is basically a start up screen that will kick you into a login screen or if you are already logged in, to the tabBarController. Below is where I transition to the tabBarController from within the viewDidAppear method.
MyViewController.m
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
UIViewController *mainTabVC = [storyboard instantiateViewControllerWithIdentifier:#"mainTabVC"];
[mainTabVC setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:mainTabVC animated:NO completion:nil];
The tabBarController in the storyboard has the identifier "mainTabVC".
I've tried lines like
MyTabBarController.managedObjectContext = self.managedObjectContext;
but I get the error Property 'MOC' not found on object of type MyTabBarController even though I do have the property declared in MyTabBarController.h
Could someone show me a line of code that I can throw in this segue to push the MOC to the tab bar controller.
BTW- I'm utilizing RestKit in this app if that changes the way I should be handling this please let me know.
*****Solution********
To make things clear for any other new guys with the same question. I went from this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
UIViewController *mainTabVC = [storyboard instantiateViewControllerWithIdentifier:#"mainTabVC"];
[mainTabVC setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:mainTabVC animated:NO completion:nil];
To this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
MyTabBarViewController *mainTabVC = [storyboard instantiateViewControllerWithIdentifier:#"mainTabVC"];
mainTabVC.managedObjectContext = self.managedObjectContext;
[mainTabVC setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:mainTabVC animated:NO completion:nil];
Notice the assignment in the third line and using MyTabBarViewController instead of UIViewController in the second line. BIG thanks again to rdelmar!
Your code is somewhat confusing. Is MyTabBarController the class? It looks like mainTabVC is your instance. You should use that rather than the class, and you should change the type when you instantiate mainTabVC to MyTabBarController, instead of UITabBarController. You also don't need to get the storyboard the way you do, you can just use self.storyboard.
MyTabBarController *mainTabVC = [self.storyboard instantiateViewControllerWithIdentifier:#"mainTabVC"];
mainTabVC.managedObjectContext = self.managedObjectContext;
[mainTabVC setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:mainTabVC animated:NO completion:nil];

Resources