Storyboards: Push a tableview into a tabbar view - uitableview

I'm new to storyboards and I'm trying to achieve this without much progress.
I have a table view controller with cells that currently push into a detail view controller.
What I want to do is to create a tab bar but only for this detail view controller (which will have 3 views that can be navigated using this tabbar).
I can't find the way to achieve this.

Ok I found out that I was setting a property using [segue destinationViewController] but with the new tabbarcontroller in the middle of the flow now I have to do this:
UITabBarController *tabBarViewController = (UITabBarController *) [segue destinationViewController];
HotelDetailViewController *hotelController = [[tabBarViewController viewControllers] objectAtIndex:0];
hotelController.hotel = hotel;

Related

Pop UIViewController using Custom Segue?

I am following this answer to "release" my previous view controller in a UINavigationController.
It works fine however the popping part is the code I am having difficult in getting to work. Basically my app works like this. It starts on a main menu (View 1) then it pushes to View 2 and I use the custom push segue to get to View 3. Now I want to use a different custom segue for popping now to go from View 3 to View 2. However, by using the code below, it pops to View 1 very quickly and then eventually pushes to View 2. It looks like the view controller transition is unnatural and I am just looking to achieve the usual pop transition just instead by using a custom segue to "release" the source view controller.
This is my code I am using now to no avail:
- (void)perform {
// Grab Variables for readability
UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];
UINavigationController *navigationController = sourceViewController.navigationController;
// Get a changeable copy of the stack
NSMutableArray *controllerStack = [NSMutableArray arrayWithArray:navigationController.viewControllers];
// Replace the source controller with the destination controller, wherever the source may be
[controllerStack addObject:destinationController];
// Assign the updated stack with animation
[navigationController setViewControllers:controllerStack animated:YES];
}
Is there something I am doing wrong here?
What you want is an "unwind" segue. More about those here: https://spin.atomicobject.com/2014/10/25/ios-unwind-segues/
If you just want to pop View 3 to go back to View 2, can't you just do something like this?
- (void)perform {
UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UINavigationController *navigationController = sourceViewController.navigationController;
[navigationController popViewControllerAnimated:YES];
}
I am not sure if this answer is localized to me but after logging my navigation stack hierarchy and playing around with the array, I did this and it works well for me.
- (void)perform {
// Grab Variables for readability
UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];
UINavigationController *navigationController = sourceViewController.navigationController;
// Get a changeable copy of the stack
NSMutableArray *controllerStack = [NSMutableArray arrayWithArray:navigationController.viewControllers];
[controllerStack replaceObjectAtIndex:1 withObject:destinationController];
[controllerStack addObject:sourceViewController];
[navigationController setViewControllers:controllerStack animated:NO];
[navigationController popViewControllerAnimated:YES];
}
A more widespread answer would probably be to find the index of the source view controller object in the array and add your destination view controller to the index before it, shifting everything from that prior index on forward one place, that way you don't mess up any of your other view controllers. As I said, the index 1 is what worked for me in this case particularly.

'Push segues can only be used when the source controller is managed by an instance of UINavigationController

I am having a problem with this.
In my root view controller I am having a textfield & one button. I am giving a condition like if i entered 0 in textfield then only it should move to next view.
upto here it is working correctly. But now here is problem. Here I am having one button & given navigation to third view controller for that button. here i am getting error as
Terminating app due to uncaught exception 'NSGenericException', reason: 'Push segues can only be used when the source controller is managed by an instance of UINavigationController.'
image ref: http://img12.imageshack.us/img12/8533/myp5.png
and i am giving action for button in first view as below
- (IBAction)Submit:(id)sender {
if([tf.text isEqual:#"0"])
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SecondViewController *vc2 = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewControllerID" ];
[self presentViewController:vc2 animated:YES completion:NULL];
}
}
Go To:
Editor--> Embed In --> Navigation Controller, to add Navigation Controller to your initial view
After looking at your screenshot, you either need to
Push your SecondViewController onto the existing navigation controller's stack instead of presenting it modally OR
You need to embed your SecondViewController in another navigation controller and then create and present that navigation controller modally from your SamplesViewController
Either way, SecondViewController needs to be embedded in a navigation controller before you can use Push Segues from it
Either embed your view controller in a Navigation controller or if there is a Navigation controller in the story board mak it the initial view controller
I also faced same problem. My problem was I was using model segue style (rather that push) for one before the current controller because of that I think it broke the Navigation chain before already.
Embed your view controller in a UINavigationController is a good option if there is no UINavigationController in the storyboard. Otherwise you can select the UINavigationController and select the root view controller in the inspector pane, then drag it to the UIViewController you want to use as root. the screenshot is as below:
I solved this by creating a custom UIStoryboardSegue between the UINavigationController and the destination view controller:
-(void) perform
{
assert([self.sourceViewController isKindOfClass:[MyNavigationController class]]);
MyNavigationController *launchController = (MyNavigationController *) self.sourceViewController;
[launchController setViewControllers:#[self.destinationViewController] animated:YES];
}
Try this. It works for me.when you set root view controller to first view and use self.presentViewController ,controller move to next view but instance of navigation controller is only for first view,third view required navigation instance so use self.navigationController instead of presentViewController.
NSString * storyboardName=#"Main";
UIStoryboard *storybord=[UIStoryboard storyboardWithName:storyboardName bundle:nil];
SecondViewController *vc=[storybord instantiateViewControllerWithIdentifier:#"SecondViewControllerID"];
[self.navigationController pushViewController:vc animated:YES];

transition from viewcontroller to tab bar controller with a navigation controller at each tab error

Hi I added a prepare for segue code in order to transfer information, however I'm getting an error.
I have a tab bar controller. It has 4 tabs. Each tab has a navigation controller, and a VC as a root view controller.
from tab 1-->nav controller-->VC 1 I need to take a value to tab2-->nav controller --->VC1
(also is the segue connected to the nav controller at tab 2, or the root view at tab 2)
Thank you in advance
error:customizableViewControllers]: unrecognized selector sent to instance 0xf19bd60
(but I am going to tab 2 (index 1))?
where is my error?
if ([segue.identifier isEqualToString:#"ResultsSegue"])
{
//the root VC at tab 2
ResultsIndexViewController*controller=[[ResultsIndexViewController alloc]init];
UITabBarController *tabController = [segue destinationViewController];
controller = (ResultsIndexViewController*)[[tabController customizableViewControllers]objectAtIndex:1];//crashing here
controller.resultsArray=[NSMutableArray arrayWithArray:_matchedResultsArray];
}
}
This part of your code
[1] UITabBarController *tabController = [segue destinationViewController];
[2] controller = (ResultsIndexViewController*)[[tabController customizableViewControllers]objectAtIndex:1];//crashing here
Is full of misconceptions.
In [1] you are assigning a destinationViewController (type UIViewController) to an object of type UITabBarController. This is compiler-legal (UITabBarController inherits from UIViewController so they are both of type UIViewController) but it doesn't reflect really what is going on. Your segue will be to the UIViewController or it's UINavigationController.
So in line [2] when you try to use your tabController as a tab bar controller, it crashes (because it isn't one).
You need to redesign your project... forget the Segue, and use the tab bar controller. Something like...
- (IBAction)moveToTab2:(id)sender {
ResultsViewController* resultsVC = (ResultsViewController*)
[[self.tabBarController viewControllers] objectAtIndex:1];
resultsVC.resultsArray=
[NSMutableArray arrayWithArray:_matchedResultsArray];
[self.tabBarController setSelectedViewController:resultsVC;
}

Set Navigation Controller Parameter from TabBarController

I've been struggling with this for quite some time and I can't seem to find anything here that directly relates. My goal is to pass a core data object from the login screen to my first view. My first view is linked to a navigation controller and the navigation controller is the first tab on a tab bar controller.
Through prepareForSegue, I can pass the object no problem to the tab bar controller but that's when things get confusing, how do I pass the object stored in the tab bar controller to the navigation controller?
Any help would be much much appreciated!
The TabBar is holding the array of ViewController and since your ViewController is inside NavigationController you can use this code to pass the object you want to the ViewController inside the NavigationControllerfrom prepareForSegue
UITabBarController *tabBarCtr = segue.destinationViewController;
UINavigationController *navigationController = [[tabBarCtr viewControllers] objectAtIndex:0];
YourViewControllerClass *viewControl = [[navigationController viewControllers] objectAtIndex:0];
viewControl.myObject = self.myObject
This works too:
UITabBarController *tabBarCtr = segue.destinationViewController;
SearchItemTypeViewController *viewControl = [[tabBarCtr viewControllers] objectAtIndex:0];

How to push from view controller to navigation view controller using prepareForSegue method?

I have a project which has a view controller as initial screen and then a view controller embedded inside a navigational view controller. I also have a button on first screen on click of which I want the navigational controller screen to be opened.
I clicked on button and then on ' connections inspector', I added push event to that navigational controller, but segue is not happening. How could I achieve it please?
SOLUTION
Finally after a bit of research I managed to get this thing working. Here is the code i am using:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"Source Controller = %#", [segue sourceViewController]);
NSLog(#"Destination Controller = %#", [segue destinationViewController]);
NSLog(#"Segue Identifier = %#", [segue identifier]);
if ([segue.identifier isEqualToString:#"mysegue"])
{
NSLog(#"coming here");
SecondViewController *loginViewController = (SecondViewController *)segue.destinationViewController;
//SecondViewController *navigationController = [[UINavigationController alloc]init];
[self presentModalViewController:loginViewController animated:YES];
}
}
Are you sure that the Navigation Controller's connection to the embedded view controller is set up correctly? The first view controller should be connected to the Navigation Controller, with a Push style segue, and the navigation controller should be connected to the second view controller, with a Relationship style segue.
At any rate, one of the official Apple tutorials does just this, so you might be able to compare your code to it and see if there's a difference: Your Second iOS App. The prepareForSegue method itself isn't really involved with firing the segue; it is just invoked before the segue runs to prepare the new view controller.

Resources