How to get viewcontroller in storyboard by identifier? - ios

I try to get a viewcontroller from storyboard like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"vc"];
ViewController *avc = ((UINavigationController *)(_window.rootViewController)).topViewController;
But they are not the same object:
(lldb) po vc <ViewController: 0x17eaee50>
(lldb) po avc <ViewController: 0x17e72970>
Why?

They are of the same class, but different instances. instantiateViewControllerWithIdentifier instantiates a new view controller, as the name implies :).

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.

How to passing data when using presentViewController with UITabbarController

I am a newbie in ios. I tried working with UITabbarController and I had some problem with it when I tried passing data from a ViewController (this ViewController is not an item in Tabbar) to an other ViewController that is item in Tabbar. In this case i wanted when I click button Login,"Welcome to shop" will appear and the username in Login form will pass into label in "Welcome to shop".
I use code below to make "welcom to shop" controller appearing:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *tabbarController= [storyboard instantiateViewControllerWithIdentifier: #"tabbarID"];
[self presentViewController: tabbarController animated: YES completion: nil];
So any idea for me to passing username (in LoginController) into label (WelcomeToShopController) ?
My problem resolved after i researched :). Because i used tabbar and navigationController so i should instance tabbar -> NavigationController -> ViewController. In my case, this code below will work perfectly.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *tabbarController= [storyboard instantiateViewControllerWithIdentifier: #"tabbarID"];
UINavigationController *nav = (UINavigationController *)[tabbarController.viewControllers firstObject];
HistoryOrderingController *historyOderingVC = (HistoryOrderingController *)[[nav viewControllers] firstObject];
historyOderingVC.user = self.user;
[self presentViewController: tabbarController animated: YES completion: nil];

Unable to present a view controller from AppDelegate

I need to present a view controller from app delegate.
When a phone notification comes in, I am able to decide which one of 3 view controllers (named ForumViewController, BlogViewController & NewsViewController) should be presented by analyzing the 'userInfo' in the method 'didReceiveRemoteNotification'.
But when i try to present the appropriate view controller using storyboards or the code below:
self.viewController = [[MembersViewController alloc] initWithNibName:#"MembersViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
Then, the app gives the error 'Warning: Attempt to present whose view is not in the window hierarchy!'. Also it gets stuck on a particular view controller.
Please keep in mind that the view controllers that I am trying to present are not part of the flow when the app starts (the flow is LogoViewController -> SplashViewController -> HomeViewController).
The HomeViewController & MembersViewController are essentially the main menu pages for public & private viewing. Here I have to display something to the viewer.
choice-1
using push
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
MembersViewController *vc = [navController.storyboard instantiateViewControllerWithIdentifier:#"MembersViewController"];
[navController pushViewController:vc animated:YES];
using present
MembersViewController *root = (MembersViewController *)self.window.rootViewController;
UIViewController *vc = [root.storyboard instantiateViewControllerWithIdentifier:#"MembersViewController"];
[root presentViewController:vc animated:YES completion:NULL];
upadted
UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MembersViewController* pvc = [mainstoryboard instantiateViewControllerWithIdentifier:#"MembersViewController"];
[self.window.rootViewController presentViewController:pvc animated:YES completion:NULL];
Loading a view controller from the storyboard:
[self performSelector: #selector(ShowModalViewController) withObject: nil afterDelay: 0];
-(void)ShowModalViewController{
NSString * storyboardName = #"MainStoryboard";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"IDENTIFIER_OF_YOUR_VIEWCONTROLLER"];
[self.window.rootViewController presentViewController:vc animated:YES completion:nil];
}
Identifier of your view controller is either equal to the class name of your view controller, or a Storyboard ID that you can assign in the identity inspector of your storyboard.

alloc init does not load component in it

i am using UINavigationController but when i push a view controller just simply by making object of the class the class load but not the components in it.
this is my AppDelegate.m
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController *vc = [sb instantiateInitialViewController];
UINavigationController *nav = [[UINavigationController alloc] init];
self.window.rootViewController = nav;
nav.viewControllers = #[vc];
and my first UIViewController if action button code is
NextView *next = [[NextView alloc] init];
[self.navigationController pushViewController:next animated:YES ];
it gets to next UIViewController but no internal components are loaded such as - button,textfield,etc.
and if i try this code it give me runtime error
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
NextView *next = [sb instantiateViewControllerWithIdentifier:#"two"];
[self.navigationController pushViewController:next animated:YES ];
make sure that NextView inherit UIViewController and you have given identifier as two to that view controller and you have set class NextView from identity inspector to that viewcontroller.
Hope this will help :)
You could not get outlets (buttons etc.) to be loaded with alloc init in the subclass of UIViewController. You should init it with the xib file, using -initWithNibName:bundle: method. Or you can instantiate it with storyboard.
// You can get current storyboard from the View Controller
UIStoryboard *sb = vc.storyboard;
NextView *next = [sb instantiateViewControllerWithIdentifier:#"two"];
[self.navigationController pushViewController:next animated:YES];

Forward a form to a view controller

I have a form design by xib file. In form have a button "Done". I want when click done button, it will forward to my view controller.
I tried code like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main.storyboard" bundle:nil];
CommentViewController *myVC = (CommentViewController *)[storyboard instantiateViewControllerWithIdentifier:#"Comment"];
[self presentModalViewController:myVC animated:YES];
But error at "presentModelViewController".
" No visible #interface for 'my form' declares the selector 'presentModalViewController'...
If self is UINavigationController, use this:
[self.navigationController pushViewController:yourViewController animated:YES];
If self is UIViewController, use this:
[self presentModalViewController:yourViewController animated:YES];
Note that: presentModalViewController: animated: is deprecated now.
The problem is that self is not a UIViewController. So you can't send presentModalViewController to self. Send it to a view controller!
UIStoryboard *loStoryboard ;
loStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil]; // Here only "Main" not "Main.storyboard".
// Instantiate the initial view controller object from the storyboard
UIViewController *initialViewController = [loStoryboard instantiateInitialViewController];
// Instantiate a UIWindow object and initialize it with the screen size of the iOS device
self.view = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Set the initial view controller to be the root view controller of the window object
[self.navigationController pushViewController:initialViewController animated:YES];

Resources