I have embedded my view controller in a navigation controller on my storyboard, then added a table view which I configured from code. I'm trying to make it, when I click a row in the table, it should change the view and putting the subview into the stack, however I can't access the navigation controller.
[self.navigationController pushViewController:disclosureView animated:YES];
When this code launches, it gives the error: " NavController[990:c07] Application tried to push a nil view controller on target . "
I hope that you didn't get call the ViewController properly :
if(indexPath.row == 0)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *disclosureView = [storyboard instantiateViewControllerWithIdentifier:#"disclosureView" ];
[self.navigationController pushViewController:disclosureView animated:YES];
Here is the screenShot for getting the UIViewController identifier:
Related
I am new to iOS as my project depends on both navigation and the UITabBar controller.I have done the following steps
UITabBar contains 4 buttons and navigation bar contains 2 buttons i.e is common to all the screens
1)first i have taken the UITabBar controller and added four buttons to it
2)For each button to the UITabBar i have added the navigation controller
When i click the tabbar buttons all the views are showing fine and coming to UITabBar bar buttons I am facing the problem as below
suppose I am in UITabBar screen "A" and i clicked the navigation bar button i got the navigation screen ex as "Navscreen"that means now "A" contains
"Navscreen" when i clicked tabbar button "B" and came back to UITabBar button "A" still its showing the "Navscreen"
To avoid such cases in the "Navscreen" view controller i have added the code as below in the view will appear
-(void)tabBarController:(UITabBarController *)tabBarController
didSelectViewController:(UIViewController *)viewController
{
NSUInteger indexOfTab = [tabBarController.viewControllers
indexOfObject:viewController];
NSLog(#"Tab index = %u (%u)", indexOfTab);
if (indexOfTab==0)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main"
bundle:nil];
FirstViewController *firstview =
(FirstViewController *) [storyboard
instantiateViewControllerWithIdentifier:#"home"];
[self.navigationController pushViewController:firstview
animated:YES];
}
else if (indexOfTab==1)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main"
bundle:nil];
secondviewcontroller *secondview =
(secondviewcontroller *) [storyboard
instantiateViewControllerWithIdentifier:#"Medremainder"];
[self.navigationController pushViewController:secondview animated:NO];
}
if (indexOfTab==2)
{
UIStoryboard *storyboard = [UIStoryboard
storyboardWithName:#"Main" bundle:nil];
mymedView *mymed_view =
(mymedView *) [storyboard
instantiateViewControllerWithIdentifier:#"mymed"];
[self.navigationController pushViewController:mymed_view
animated:NO];
}
if (indexOfTab==3)
{
UIStoryboard *storyboard = [UIStoryboard
storyboardWithName:#"Main" bundle:nil];
Event_view *event_view =
(Event_view *) [storyboard
instantiateViewControllerWithIdentifier:#"Event_view"];
[self.navigationController pushViewController:event_view
animated:NO];
}
}
But in this case when click "Navscreen" its working and when I click the UITabBar "B" iam able to get the UITabBar screen.If i click again UITabBar "A" i can see "A" and when i click the UITabBar button "B" app is crashing.AS i am new to ios please help me with the possible solution if i make any thing wrong please suggest with the correct solutions.
In your didSelectViewController:, you seem to be pushing new controllers onto self.navigationController multiple times? Each time you select a tab this code will push another controller loaded from storyboard on top of what is already there. This is probably what is messing up your navigation items.
Should you not just be allocating separate navigation controllers once to each tab so this is all automatic?
In storyboard/code allocate separate navigation controllers for each tab. In each navigation controller, create it with a root controller based on what you are loading from storyboard for each tab. You only need to create this once somewhere in your main controller. Then allocate the navigation controllers to separate tabs in storyboard or in code set the array of controllers to be an array of your created navigation controllers.
It should then all be automatic without you needing to implement didSelectViewController: at all since each tab will simply cause the appropriate navigation controller to be presented and its associated navigation bar.
I have a problem when trying to push a new view controller onto an existing navigation controller.
The thing I'm trying is to make a UIPopoverController appear when pushing a navigation UIBarButtonItem, and from that "dropdown" select a menu point which will push the associated view controller onto the "main" navigation controller.
I've tried the following, which gives a modal. But I want the view pushed.
If selecting push instead of modal the result is as following.
I've also tried making a custom UITableViewController (on the popover) from which I've tried the following code:
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController *dash = [storyboard instantiateViewControllerWithIdentifier:#"dash_nav"];
UIViewController *students = [storyboard instantiateViewControllerWithIdentifier:#"students"];
if (indexPath.row == 0) {
[dash pushViewController:students animated:YES];
// [[dash navigationController] presentViewController:students animated:YES completion:nil];
}
NSLog(#"%#", [dash title]);
NSLog(#"index = %i", indexPath.row);
}
Is there a way to do what I am trying to accomplish?
This code:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController *dash = [storyboard instantiateViewControllerWithIdentifier:#"dash_nav"];
UIViewController *students = [storyboard instantiateViewControllerWithIdentifier:#"students"];
is creating too many new instances. You should be using the existing storyboard (self. storyboard) and the existing navigation controller. The navigation controller needs to be passed to the table view controller (which you should use because the storyboard doesn't have the required information). We'll call this originatingNavigationController, a new #property on the table view controller.
When the segue triggers to show the popover, set the navigation controller reference into the destination view controller (the table view).
Then, in the didSelectRowAtIndexPath: method you just instantiate the students VC and push it:
UIViewController *students = [self.storyboard instantiateViewControllerWithIdentifier:#"students"];
[self.originatingNavigationController pushViewController:students animated:YES];
and then the table view controller should dismiss itself (its popover).
I have a combination of a storyboard and NIB viewcontrollers how can I segue from one to the other
This is the Scenario:
UITabBarController(storyboard)|- UINavigationController (subclassed in storyboard) -> [UIViewController (NIB)] -> UIViewController (in Storyboard)
You'll have to give the UIViewController in the Storyboard a 'Storyboard ID' (in the Identity inspector tab). Then instantiate that ViewController in your NIB ViewController's code like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
ViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"YourViewControllerId"];
[self.navigationController pushViewController:vc animated:YES];
In your UINavigationController subclass you need to instantiate your view controller with its view in a NIB(let's call it NIBViewController) and set that view controller as the rootViewController with the method setViewControllers:animated:. Do it in awakeFromNib like this:
- (void)awakeFromNib
{
[super awakeFromNib];
NIBViewController *viewController = [[NIBViewController] init];// It will look for the appropriate XIB as long as you did not change its name and it's in the main bundle, otherwise use initWithNibName:bundle:
[self setViewControllers:#[viewController] animated:NO];
}
Then, to go from the NIBViewController to other view controller contained in the storyboard just set an identifier in the storyboard for that view controller, instantiate it and push it or present it, as you want.
It is important to mark that in your NIBViewController instance self.storyboard will be nil because that view controller is not contained in a storyboard, so you need to instantiate a new storyboard(solution A**) or get the storyboard from the navigation controller(solution B):
// Solution A
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
// Solution B
UIStoryboard *storyboard = [self.navigationController storyboard];
UIViewController *storyboardViewController = [storyboard instantiateViewControllerWithIdentifier:#"viewControllerId"];
[self.navigationController pushViewController:storyboardViewController animated:YES];
** Please note that this is creating a new instance of the storyboard, so better not to try tricky things and avoid segues to previous view controllers contained in the storyboard or you will find that those view controllers are not the same ones... It's the first solution that came to my mind, but definitely you should go for the solution B.
segues not working after going to destination view controller (which is in storyboard )programmatically from a button click of view controller (which is not in storyboard)
- (IBAction)OK:(id)sender {
UIStoryboard *myStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
mainViewController *controller = (mainViewController *)[myStoryboard instantiateViewControllerWithIdentifier:#"mainViewController"];
[controller setModalPresentationStyle: UIModalPresentationFormSheet];
[self presentModalViewController:controller animated:YES];
}
Okey, if i am not wrong, i think , the button click segue is using navigationcontroller , if so , watch your custom segue ,
[self presentModalViewController:controller animated:YES];
you are making an model segue, so your navigation controller will be unknown after the segue is done.
There is probably a simple solution but I can't figure it out.
I am using storyboards for the interface.
I start with a tab bar controller, but before the user is allowed to use the app the user has to authenticate himself trough a loginview which is modally pushed at the start.
I want to configure the loginview at the same storyboard, but I can't seam to figure out how to link the view controller at the storyboard and my code.
What I have done:
Create a new UIViewController subclass trough file > new > new file.
Drag a new UIViewController in the story board
Set the class in the custom class tab
drags a UILabel for test purpose.
run
No label...
Pull on a new UIViewController that will act as the login view controller onto the MainStoryboard. In the attribute inspector change the identifier to LoginViewController (or something appropriate). Then add
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:vc animated:YES];
}
to the First view controller and the login screen will be loaded from your storyboard and presented.
Hope this helps.
The answer by Scott Sherwood above is most correct answer I found after lot of searching. Though very slight change as per new SDK (6.1), presentModalViewController shows deprecated.
Here is very small change to above answer.
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
HomeViewController * hvc = [sb instantiateViewControllerWithIdentifier:#"LoginView"];
[hvc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:hvc animated:YES completion:nil];
I'm new in this field. But if the first view controller is a navigation view controller and its rootviewcontroller is a table view controller. If you want to push a view controller like the LoginViewController when you click the cell, and you also want to go back to the table view by using the navigation bar. I recommend this way:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *controller = [sb instantiateViewControllerWithIdentifier:#"LoginViewController"];
[self.navigationController pushViewController:controller animated:YES];
}
In this way, you can have the navigation.
By the way, I don't know why this kind of problem you asked will appear. I guess when the loginviewcontroller is created in the code, its view is not the view in the storyboard. If someone know the cause, please tell me! thanks!