After Pushing View Controller Load a View From Storyboard - ios

I am trying to have a different view controller appear as you change the device orientation and for that I am using a UINavigation Controller. When I call for the other view controller to be pushed [self.navigationController pushViewController:graphView animated:YES]; It makes the transition but the screen is black and does not load this new controller "graphView"'s view which is white with text. I have done graphView = [[GraphView alloc] init]; for the new controller but i do not have any storyboard connections made from the current view to the graph view nor do I have anything in my new view controller other than:
- (void)viewDidLoad {
//[super viewDidLoad];
NSLog(#"loaded");
}
Is there an extra step since this is a new view controller to load the view from this view controller that i have on my storyboard? Also the log does work meaning that is corrent.

Instead of initializing your 'graphView' like:
graphView = [[GraphView alloc] init];
You'll need to do this:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
graphView = [storyboard instantiateViewControllerWithIdentifier:#"YourViewControllerId"];
**And make sure you set your ViewController's storyboard identifier in the storyboard:
Select your ViewController
Click the Identity inspector
Set the Storyboard ID ('YourViewControllerId' above)
Then, calling pushViewController:animated: as you were should present your ViewController appropriately.

Related

Navigation View Controller from Subview

I have been working on this problem for a while and thought I would ask for some help. I have 3 view-controllers: 1 Navigation Controller, 1 Main controller and 1 detail view controller.
Within the main view controller, I have a series of subviews with buttons. Due to the class structure, however, I am unable to directly call self.storyboard to get the current storyboard object.
I have tried 2 different methods, a variety of ways, and am still unsuccessful. I posted my methods below and described what is and what is not happening in each segment. The overall goal is to present a child view controller (the detail view) by tapping a button in a subview, of which does not have access to the parent storyboard directly.
Method 1
//Instantiate the new view controller
ProfileViewViewController *tempViewToShow = [del.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"profile"];
// Pass data into the new view controller
tempViewToShow.thisUser = self.postUser;
// Output a simple log to ensure both were created
NSLog(#"Temp User Name: %#, Profile Desc: %#", [tempViewToShow.thisUser getFullName], tempViewToShow.description);
// Using the AppDelegate for the RootViewController, present the detail view
[UIApplication.sharedApplication.delegate.window.rootViewController presentViewController:tempViewToShow animated:YES completion:NULL];
Issues
The issue with this series is that the detail view does not carry the navigation controller (since it is not mentioned), however, this way still shows a full View Controller
Method 2
...
// Use the Delegate and the navigation controller to present the new view controller
[UIApplication.sharedApplication.delegate.window.rootViewController.navigationController presentViewController:tempViewToShow animated:YES completion:NULL];
Issues
Does not display anything
Method 3
// Use the recommended 'pushViewController' for the navigation controller to carry over
[UIApplication.sharedApplication.delegate.window.rootViewController.navigationController pushViewController:tempViewToShow animated:NO];
Issues
Does not display anything
En toto, how would I make this work? What lines would I modify and how? Thanks!
You can solve this issue like this:
ProfileViewViewController *tempViewToShow = [del.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"profile"];
UINavigationController *naviController = [[UINavigationController alloc] tempViewToShow];
And then do this :
[UIApplication.sharedApplication.delegate.window.rootViewController presentViewController:naviController animated:YES completion:NULL];
You can create instance of storyboard from storyboard name.once you have correct storyboard instance, get NavigationController from Its identifier, and detailviewController from its identifier. Push detailviewcontroller on Navigationviewcontroller.
get storyboard-- replace name of your storyboard in "MainSToryboard"
UIStoryboard *storyboard =
[UIStoryboard storyboardWithName:#"MainStoryboard"
bundle:[NSBundle mainBundle]];
get instance of Navigationcontroller - replace identifier:
UINavigationController *navController =(UINavigationController *)
[storyboard instantiateViewControllerWithIdentifier:#"navcontroller"];
get detailviewconrtoller :
UIViewController *detailvc=
[storyboard instantiateViewControllerWithIdentifier:#"profile"];
Push detail on current navigationcontroller:
[navController pushViewController:detailvc animated:YES];
I found an alternate solution. The cause was because the incorrect view controller was being called by
UIApplication.sharedApplication.delegate.window.rootViewController.*
The workaround is:
In the primary view controller class, I passed the displayed viewcontroller into the delegate class. Then, from the child class I wanted to call, I referenced that view controller, and navigation controller, and it worked just fine. My final code is below:
// Create the detail View Controller
ProfileViewViewController *tempViewToShow = [del.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"profile"];
// Set the user variable in the detail view controller
tempViewToShow.thisUser = self.postUser;
// Push the view controller into the navigation controller
// Note that del.currentNav comes from this code:
/*
* In this class, create the delegate reference
* AppDelegate *del = (AppDelegate *)[[UIApplication sharedApplication] delegate]
*
* In the Delegate class, get the set the current navigation controller {let currentVC : UIViewController = passedInVC}
* self.currentNav = currentVC.navigationController;
*/
[del.currentNav pushViewController:tempViewToShow animated:YES];

Xcode 6 - Added Navigation Controller to storyboard, but not appearing in app

I added a Navigation Controller to my storyboard and it appears like so:
Now in the table view controller, I gave the TableViewController a storyboard id and class to a TableViewController Controller
When I run my app, I don't see the Navigation Bar at the top. This has been extremely frustrating and can't find a solution anywhere. PLEASE HELP
To get to the scene, someone clicks a button and this code runs and it goes to my Table View Controller:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
LHFileBrowser *LHFileBrowser = [storyBoard instantiateViewControllerWithIdentifier:#"FileBrowser"];
[self.navigationController pushViewController:LHFileBrowser animated:YES];
[self presentViewController:LHFileBrowser animated:YES completion:nil];
The error is in your code.
If you want to (modally) present a view controller when the user presses a button, you need to present the navigation controller (which will contain the table view controller), not the table view controller itself.
Right now, you're presenting the view controller, which won't show it being embedded in a navigation controller.
Also, you're mixing up two different approaches, by trying to push a view controller onto a navigation controller stack, and also presenting the view controller.
Code Sample:
Here's what you apparently mean to do:
UIStoryboard *storyboard = self.storyboard;
UINavigationController *navigationController = [storyboard instantiateViewControllerWithIdentifier:#"MyNavigationControllerID"];
LHFileBrowser *rootViewController = [navigationController topViewController];
// Configure your LHFileBrowser view controller here.
rootViewController.someProperty = ...;
// Modally present the embedded view controller
[self presentViewController:navigationController animated:YES completion:nil];
If you want to change the presentation or transition style, you can set those details in your storyboard.
You didn't explain why you had to programmatically add buttons, but Storyboard segues would have instantiated and presented an embedded view controller for you, without you having to have done it in code.
The more you can do in Storyboard, the less code you have to maintain, support, and update, and the more likely your app will still work properly when a new SDK is released.
Update:
The better way to do this is to let Storyboard do it for you, by adding a segue from the button to the navigation controller that you want to present.

load viewcontroller within a tabbar control

on viewdidload of one of my tabbar viewcontrollers I'll like to display or popup another view controller. here's my code
if (_history.count == 0) {
//[self performSegueWithIdentifier:#"emptyHistorySegue" sender:self];
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MSAEmptyHistoryViewController *popupController = [sb instantiateViewControllerWithIdentifier:#"EmptyHistoryViewController"];
[self presentViewController:popupController animated:NO completion:nil];
}
The load the viewcontroller on top of the tabview controller. I need this view to display but still allow the user to see the tabbar buttons.
You will run into problems if you try to transition to another view controller in viewDidLoad. You should either switch the child view controllers of the tab bar controller or you can present a subview within one of the child view controllers.
When -viewDidLoad is called, the view controller is generally not presented. As such, if you try to present another controller, it will crash.
Try -viewDidAppear: if you want what you are describing.

Proper Way to Open a New Storyboard through UITabBarController

We are working on splitting our main storyboard into smaller ones so that it makes source control merging easier. Any ideas on what the right approach is to load a new storyboard from a UITabBar?
Here's what we have so far in our custom subclassed UITabBarController:
UITabBarItem *cardsTabItem = [self.tabBar.items objectAtIndex:kTabBarIndexCards];
cardsTabItem.image = [[UIImage imageNamed:#"navCardsOff"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
cardsTabItem.selectedImage = [[UIImage imageNamed:#"navCardsOn"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
cardsTabItem.imageInsets = UIEdgeInsetsMake(-5, 0, 5, 0);
cardsTabItem.titlePositionAdjustment = UIOffsetMake(0, -5);
I've done the same thing before, but with a UITabBarController. In that case we had a storyboard for each of the tab buttons, even though one of the storyboards only had 1 view controller in it. I think wether you're using a UITabBarController or responding to the tab bar delegate the answer is the same. For each button clicked make the determination of which storyboard the view controller you want to load is in:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"leftButtonStoryboard" bundle:[NSBundle mainBundle]];
UIViewController *vc = [storyboard instantiateInitialViewController];
//or
UIStoryboard *otherVC = [storyboard instantiateViewControllerWithIdentifier:#"CameraViewController"];
Then you can present it, push it, or whatever.
In my case since I was using a UITabBarController this was all done during initialization of the controller for all the different buttons.
It will most likely come in handy to by default name all of the different view controller your using in your storyboard (the storyboard id), I usually name them after the viewController class so I don't have to remember what I called it.
I would also recommend that you avoid using the self.storyboard property when trying to instantiate another view controller because you might end up with a situation where a controller is shared between tabs. Being explicit with which storyboard you're loading a controller from can help with readability and avoidance of bugs.
Edit - a more concrete example:
What you need to do is set the viewControllers property of your UITabViewController, I do this in its init method. For example
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
UIViewController *one = [mainStoryboard instantiateViewControllerWithIdentifier:#"VC1"];
UIViewController *two = [mainStoryboard instantiateViewControllerWithIdentifier:#"VC2"];
self.viewControllers = #[one,two];
}
return self;
}
You can use this technique if your writing it in code itself or if you're using a storyboard. Beware that if you have other view controllers already hooked up via the storyboard you'll loose then unless you instantiate them there as well. You can also use the setViewControllers: animated: method as well.
The code for creating the custom tab bar items (the buttons at the bottom) should probably go within the individual view controllers and be assigned to its tabBarItem property. The UITabBarController will use that property to create the correctly styled button. If you don't provide the property you get the default buttons starting from 1.

How to add a custom splash that dissapears after a custom time to allow for webview to load. Objective-c

I'm using this code to show a splash screen but the only thing I see is black.
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPad" bundle:nil];
SplashViewController *splash = [storyBoard instantiateViewControllerWithIdentifier:#"splash"];
splash.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
splash.modalPresentationStyle = UIModalPresentationFullScreen;
[self.window addSubview:splash.view];
The view controller of the splash screen is loading because the break points are being called but I cant see the view controller I just see black.
I think instead of adding splash.view as window subview you can use presentViewController:animated:completion: to present the splash view controller.
I see you are using storyboard, so this is what you can do:
- Add view controller (VC0) to storyboard
- Set correct orientation on VC0 - your app orientation
- Add container view on VC0 (full size view)
- Add splash screen image on VC0 (full size view)
- Create UIViewController subclass - call it for example CustomSplashDisplay
- create UIImageView IBOutlet - for example vwImage
- override viewDidLoad like:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self performSelector:#selector(HideImage) withObject:nil afterDelay:kSplashScreenDuration];
}
-(void)HideImage
{
[vwImage setHidden:YES];
[self.view sendSubviewToBack:vwImage];
}
in storyboard
- Set VC0 as initial view controller
- Set its class to CustomSplashDisplay
- connect UIImage outlet
- embed previous initial view controller in container view
run an here you go...

Resources