Objective C: Load storyboard from a pod/framework - ios

I'm trying to load a view controller that's in a .storyboard in a pod. I'm using the following which normally works:
UIStoryboard *storyboard = [UIStoryboard
storyboardWithName:#"StoryboardName" bundle:nil];
NewViewController *newView = [storyboard instantiateViewControllerWithIdentifier:#"NewViewController"];
[self.navigationController pushViewController:newView animated:YES];
What do I need to change it to so I can load from a pod?

You should load it with it's bundle identifier
NSBundle* bun = [NSBundle bundleWithIdentifier:"id"]
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"StoryboardName" bundle:bun];

Related

Initialize Swift storyboard from Objective-C

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.

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;

Could not load NIB in bundle: 'NSBundle ยทยทยท with name 'chosenCountry''

I want touch the UIBarButtonItem in the top right, and push a new viewController. So, the code is:
UIBarButtonItem *addButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(insertNewObject)];
self.navigationItem.rightBarButtonItem = addButton;
and method insertNewObject is:
-(void)insertNewObject{
chosenViewController *chosenCountry = [[chosenViewController alloc]initWithNibName:#"chosenCountry" bundle:nil];
//self.chosenViewController = chosenCountry;
[self.navigationController pushViewController:chosenCountry animated:YES];
}
but XCode have a error when I run 'Could not load NIB in bundle: 'NSBundle ...(loaded)' with name 'chosenCountry''
How can I fix it?
Thanks!
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"chosenCountry"];
[self.navigationController pushViewController:vc animated:YES];
Since you have added your vc in storyboard, hence initWithNibName will not work.
Either use segue or use storyboard's method instantiateViewControllerWithIdentifier to instantiate the view controller
Use this code it works for you
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
yourViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"chosenCountry"];
[self.navigationController pushViewController:vc animated:YES];

Obj-C Change ViewController programmatically (Two storyboards)

First of all, I want to highlight, that this code is working, but bad-looking. I need to change view controller programmatically (can't use segue), so I use this code:
NSString *storyboardName = #"Main";
UIStoryboard *storyboard =
[UIStoryboard storyboardWithName:storyboardName bundle:nil];
PurchaseViewController *vc = [storyboard
instantiateViewControllerWithIdentifier:#"PurchaseViewController"];
[controller presentViewController:vc animated:YES completion:nil];
Obvoiusly its working. Unfortunately after create 2nd storyboard (iPad) I was forced to change this code to:
#define IDIOM UI_USER_INTERFACE_IDIOM()
#define IPAD UIUserInterfaceIdiomPad
/*
...
*/
NSString *storyboardName;
if (IDIOM == IPAD)
storyboardName = #"Main_iPad";
else
storyboardName = #"Main";
UIStoryboard *storyboard =
[UIStoryboard storyboardWithName:storyboardName bundle:nil];
PurchaseViewController *vc = [storyboard
instantiateViewControllerWithIdentifier:#"PurchaseViewController"];
[controller presentViewController:vc animated:YES completion:nil];
It must be better solution than this, but I didn't found one. Do you know alternative(better) solution?
Keep your iPad Storyboard name same as iPhone just append '~ipad' before '.storyboard' and add 'Main storyboard file base name (iPad)' in info.plist and put Storyboard name as value. Then use below code to get storyboard name according to device.
NSBundle *bundle = [NSBundle mainBundle];
NSString *storyboardName = [bundle objectForInfoDictionaryKey:#"UIMainStoryboardFile"];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:storyboardName bundle:bundle];
Hope this will help.

error opening the storyboard files

in my project i have different Storyboard files to support different iPhones, i have this code in my appDelegate:
if (window.frame.size.height == 568){
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:kMain5Name bundle:[NSBundle mainBundle]];
id rootViewController = [storyBoard instantiateInitialViewController];
[window setRootViewController:rootViewController];
} else if (window.frame.size.height == 480){
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:kMain5Name bundle:[NSBundle mainBundle]];
id rootViewController = [storyBoard instantiateInitialViewController];
[window setRootViewController:rootViewController];
} else if (window.frame.size.height == 667){
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:kMain6Name bundle:[NSBundle mainBundle]];
id rootViewController = [storyBoard instantiateInitialViewController];
[window setRootViewController:rootViewController];
} else if (window.frame.size.height == 736){
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:kMain6plusName bundle:[NSBundle mainBundle]];
id rootViewController = [storyBoard instantiateInitialViewController];
[window setRootViewController:rootViewController];
}
every time i compile and run the app crashes saying it could not find storyboard file in NSBundle, i tied commenting out the above code and it worked again. is there something wrong with my code?
Here is an excerpt from UIStoryboard Class reference
Parameters
name
The name of the storyboard resource file without the filename extension. This method raises an exception if this parameter is nil.
I made the relevant part bold. In case you are not a native speaker, it means do not add the extension into the parameter. But you did exactly that in your macro.
You really should read the documentation before trying to find some more esoteric cause for any problems in code.

Resources