Can a UITabBarController be a segue.destinationViewController? - objective-c

I have a UITabBarController with three tabs: each is a navigation controller with a view controller embedded. Currently the tabController is the initial view controller. I would like to place an intro view controller with buttons that precedes the tabController, with buttons that segue to the tabController. I'm using Xcode 4.2 and storyboards.
Is this possible?
In my IntroViewController I call prepareForSegue. It is not working:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"tabSegue"]) {
FirstViewController *firstVC = [[FirstViewController alloc]init];
SecondViewController *secondVC = [[SecondViewController alloc] init];
ThirdViewController *thirdVC = [[ThirdViewController alloc]init];
self.tabBarController = segue.destinationViewController;
UINavigationController *navController1 = [[UINavigationController alloc]initWithRootViewController:firstVC];
UINavigationController *navController2 = [[UINavigationController alloc]initWithRootViewController:secondVC];
UINavigationController *navController3 = [[UINavigationController alloc]initWithRootViewController:thirdVC];
NSArray *tabViewArray = [NSArray arrayWithObjects:navController1,navController2,navController3, nil];
tabBarController.viewControllers = tabViewArray;
}
}
In summary, can you segue to a tabBarController?

As the comment states, I used self.tabBarController = segue.destinationViewController.

Thanks Ar No.
My situation was to pass object value from view 1 to 2.
NavControl - ViewController(1)
TabbarControl - NavControl - ViewController(2)

Related

Set Root View In App delegate with View Hierachy

I want to be able to manually set the root view controller in app delegate intact with it's view hierarchy
My View Controller Hierarchy is
TabBarController
UINavigationController
FirstViewController
DetailedViewController (I want to show this view)
Currently what I do is
DetailedViewController *vc = (DetailedViewController *)[mainStoryBoard instantiateViewControllerWithIdentifier:#"DetailedViewController"];
[self.window setRootViewController:vc];
[vc performSelector:#selector(setup:) withObject:section];
which obviously ignores the hierarchy and therefore when the app loads, I dont have the nav bar nor the tab bar.
So I tried this
UITabBarController *tabBarController = [mainStoryBoard instantiateViewControllerWithIdentifier:#"tabController"];
tabBarController.selectedIndex = 0;
DetailedViewController *vc = (DetailedViewController *)[mainStoryBoard instantiateViewControllerWithIdentifier:#"DetailedViewController"];
UINavigationController *navController = [mainStoryBoard instantiateViewControllerWithIdentifier:#"NavController"];
[navController pushViewController:vc animated:YES];
[self.window setRootViewController:tabBarController];
But using this code I can view FirstViewController and not the DetailedViewController
Your view hirarchy is such that
You have tabbar that has navcontroller with a rootview of firstviewcontroller so this code add firstview as rootView
UITabBarController *tabBarController = [mainStoryBoard instantiateViewControllerWithIdentifier:#"tabController"];
tabBarController.selectedIndex = 0;
FrstViewController *firstView = (FirstViewController*)[mainStoryboard instantiateViewControllerWithIdentifier:#"FirstViewController"];
UINavigationController *navController = [UINavigationViewController alloc] initWithRootViewController:firstview]
self.tabbarController.viewControllers = [NSArray arrayWithObjects:navController,nil]
[self.window setRootViewController:tabBarController];
When the first we loads in viewDidload of it push detailviewcontroller
-(void) viewDidLoad
{
DetailedViewController *vc = (DetailedViewController *)[mainStoryBoard instantiateViewControllerWithIdentifier:#"DetailedViewController"];
[self.navigationController pushViewController vc];
}

Navigation with xib in iOS app

Please, help to understand the navigation. I'm working with xibs. The scheme is: https://www.dropbox.com/s/o82fxpte0hmyxcq/Scheme_Simple.jpg .
Here's my code :
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
FirstViewController *firstViewController = [[firstViewController alloc] initWithNibName:#"firstViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}
#implementation FirstViewController
- (IBAction)button1Tapped:(id)sender {
SecondViewController *secondViewController = [[SecondViewController alloc] init];
secondViewController.title = #"View2";
[self.navigationController pushViewController:secondViewController animated:YES];
}
#implementation SecondViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ThirdViewController *thirdViewController = [[ThirdViewController alloc] init];
thirdViewController.title = #"View3";
if (indexPath.row == 0) {
[self.navigationController pushViewController:thirdViewController animated:YES];
[secondViewTableView deselectRowAtIndexPath:indexPath animated:YES];
}
}
So, I have questions:
Where should I create the next view? In my code view has created in "previous" class: view2 created in FirstViewController, view3 created in SecondViewController etc. All new ViewControllers are inside the method that initiates the navigation, is it right way? I think it's wrong, but the navigation is working.
Problems with headers in the navigation bar. It turns out that the title of view2 is only displayed when moving from view1 to view2, but when going back from view3 to view2 – header disappears. I googled, tried to add self.title = #"name" to viewDidLoad, initWithNibName, viewWillAppear – none of this works.
So I've solved the problem with disappearing title of navigation bar. The problem was in my custom back button: self.navigationItem.title = #"";
It was working and title "Back" from my back button disappeared but also title of navigation bar disappeared too. The right way to make back button untitled is:
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStyleBordered target:nil action:nil];
[self.navigationItem setBackBarButtonItem:backButton];

Correct way to pushViewController in this case?

I have a custom UITabBarController. On it I have added 3 view controllers adding a navigationController to each one first. It looks like this
· customTabBarController.m viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
FirstViewController *firstController = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UINavigationController *firstNavController = [[UINavigationController alloc] initWithRootViewController:firstController];
SecondViewController *secondController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
UINavigationController *secondNavController = [[UINavigationController alloc] initWithRootViewController:secondController];
self.viewControllers = [NSArray arrayWithObjects:firstNavController, secondNavController, nil];
[self addLeftButtonImage];
[self addRightButtonImage];
self.selectedIndex = 1;
}
Now, when I am on a view controller and I want to pushViewController, how do I have to call it?

UINavigationBar and UITableView in Xcode 4.3.2

Did you notice that UINavigationBar is not set anymore when creating a UITableView, even after giving it a title or a button?
Now i'm going mad on how to put a navigation bar over my UITableView. It seems really impossible. I tried to add to my tableView a subview with the Navigation Bar, but seems worthless, because when I scroll down, the navigation bar scrolls down as wellm and it shouldn't.
Any ideas on how to implement it?
EDIT
Well, as always I went on File -> New -> File.. -> UITableView. Then i set a bit of code and when I wrote
self.navigationItem.title = #"MyTitle";
self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
and tried to test on Simulator, no Navigation Bar appeared.
My init code:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = #"TabTitle";
self.tabBarItem.image = [UIImage imageNamed:#"img.png"];
self.view.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
}
return self;
}
I can't explain why it doesn't appear anymore. I also tried to create a new project and import my classes from a project where the navigation bar appeared, but same result there too.
EDIT2*
The app is a tabBased application.
Here is the code took from the App delegate used to set up the tabBar.
UIViewController *viewController1, *viewController4;
UITableViewController *viewController2, *viewController3;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
viewController1 = [[FirstViewController alloc] initWithNibName:#"First_iPhone" bundle:nil];
viewController2 = [[Tips alloc] initWithNibName:#"Table" bundle:nil];
viewController3 = [[Favorites alloc] initWithNibName:#"Test_iPhone" bundle:nil];
viewController4 = [[SecondViewController alloc] initWithNibName:#"Second_iPhone" bundle:nil];
}
You are initing an UITabBarController and set 4 UIViewControllers as the corresponding UITabbarViewControllers. Since two of them are normal UIViewControntroller and two are UITableViewController there can not be a navigation bar. You have to load the viewController where you'd like the navbar form a UINavigationController. The correct way would be (assuming vc3 is the one where you'd like the navbar):
UIViewController *viewController1, *viewController4;
UITableViewController *viewController2, viewController3;
UINavigationController *vc3NavController;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
viewController1 = [[FirstViewController alloc] initWithNibName:#"First_iPhone" bundle:nil];
viewController2 = [[Tips alloc] initWithNibName:#"Table" bundle:nil];
viewController3 = [[Favorites alloc] initWithNibName:#"Test_iPhone" bundle:nil];
vc3NavController = [[UINavigationController alloc] initWithRootViewController:viewController3];
viewController4 = [[SecondViewController alloc] initWithNibName:#"Second_iPhone" bundle:nil];
}
Then load the vc3NavController instead of viewController3 as the corresponding tab.
So you have: UITabBarController -> UINavigationController -> YourViewController
Maybe Creating a Navigation Interface will help you too.

UITabBarController with a UIPopOverController with Multiple Views

I am working on a small app, according to the requirement the app should have a tabBarItem with 3 items. For this I have programmatically created the tabBarController in the AppDelegate.m file and added the 3 different viewControllers, instantiated them and everything is working good. I see the tabBarItems and all views are working. In one of the views lets say in SecondViewController I show a popOverController where I used a UITableView and populate it with items. When I click one of the items it should show another view lets say sendFeedback. Until there everything is working fine, but as soon as this sendFeedback is presented as the modal view, it occupies the whole app i.e it hides the tabBarItem.
I present the important pieces of code here for review:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
viewController1.title = #"First";
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
viewController2.title = #"Second";
UITableViewController *tableView3 = [[tableViewController alloc]initWithNibName:#"tableViewController" bundle:nil];
tableView3.title = #"Third";
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, tableView3 ,nil];
self.tabBarController.delegate = self;
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
[viewController1 release];
[viewController2 release];
[tableView3 release];
return YES;
}
In my popOverViewController.m file I am checking which row is selected in the table according to that I present the view
#pragma mark - TableView Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
sendFeedback *sendEmailViewController = [[sendFeedback alloc]initWithNibName:#"sendFeedback" bundle:nil];
downLoad *downloadFilelViewController = [[downLoad alloc]initWithNibName:#"downLoad" bundle:nil];
if (indexPath.row == 0)
[self presentModalViewController:sendEmailViewController animated:YES];
else
[self presentModalViewController:downloadFilelViewController animated:YES];
}
Can anyone guide me how to overcome this with the multiple views. In case if anyone requires more information from my side I would be glad to provide.
NOTE: It is the same with the other view (downLoad) as well
EDIT: Here is how I am initializing my PopOverController in the AppDelegate.m file
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if([viewController isKindOfClass:[SecondViewController class]]){
NSInteger index = [[self tabBarController] selectedIndex];
CGRect buttonFrame = [[[[[self tabBarController] tabBar] subviews] objectAtIndex:index+1] frame];
PopOverViewController *popoverView = [PopOverViewController new];
popoverView.contentSizeForViewInPopover = CGSizeMake(250, 85);
popover = [[UIPopoverController alloc]initWithContentViewController:popoverView];
NSLog(#"X:%f Y:%f",buttonFrame.origin.x,buttonFrame.origin.y);
[popover presentPopoverFromRect:buttonFrame inView:self.tabBarController.tabBar permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
Thanks
Modal view controllers are used to "block" your application and fulfill a task before you can proceed. So modal view controllers are not what you want to use.
Instead wrap your controllers which have to be shown in the popover in a navigation controller. In the tableView:didSelectRowAtIndexPath: method you can push the corresponding view controller to the navigation stack.
To slove your problem:
At the place where you create the popovercontroller initialize it with a new UINavigationController. And the navigation controller you have to initialize with a rootviewcontroller namely PopOverViewController.m.
PopOverController *popoverContentController = [[PopOverController alloc] init];
UINavigationController *navcon = [[UINavigationController alloc] initWithRootViewController:popoverContentController];
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContentController];
And in PopOverController.m
if (indexPath.row == 0)
[self.navigationController pushViewController:sendEmailViewController animated:YES];
else
[self.navigationController pushViewController:downloadFilelViewController animated:YES];