Managing navigation controllers / view controllers - objective-c

Not sure how to title this question, but i'v got such a problem: Up until now i my app runs mainly in one navigationcontroller with table views. But now i'm trying to integrate dropdown settings menu, and can't get it properly done.
The way i'v done now and it works
The changeController is called from one button. ChangeController is in appdelegate.
- (void) ChangeController
{
self.window.backgroundColor = [UIColor blackColor];
DropDownExample *e = [[DropDownExample alloc] initWithStyle:UITableViewStyleGrouped];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:e];
[e release];
[self.window addSubview:self.navigationController.view];
self.window.backgroundColor = [UIColor blackColor];
[self.window makeKeyAndVisible];
}
But this approach has consequances - there is no transition if button is pressed, the settings menu appears instantly, you cannot go back via navigation bar above (nothing there).
So how to do this properly?? I'm new to ios, so just tell me the whole idea how to do this.
Didfinishlaunchingwithoptions method from appdelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease
];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
TableViewController *tableVC = [[TableViewController alloc] initWithNibName:#"TableView" bundle:nil andType:CONTROLLER_TYPE_FIRST];
UINavigationController *navC = [[UINavigationController alloc] initWithRootViewController:tableVC];
self.navigationController = navC;
[tableVC release];
[navC release];
self.window.rootViewController = _navigationController;
[self.window makeKeyAndVisible];
return YES;
}

Ok, here's the answer. Write the method changeController in the same class where the Button exists which calls changeController
In the method, write this.
- (void) ChangeController
{
DropDownExample *e = [[DropDownExample alloc] initWithStyle:UITableViewStyleGrouped];
[self.navigationController pushViewController:e animated:YES];
[e release];
}
What you want is to insert new UIViewController on the top of the present Stack. If you would be having a navigation Bar at the top by default then there would be a back Btn by default, which would pop up that controller.

Related

UiTabBarController's tabs aren't showing at all but functional, what could be causing this issue?

As you can see in the image below the tab bar is visible but the tabs aren't. However I am still able to click where both of the tabs would be and flick between 2 views.
What could be wrong?
AppDelegate Code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
HypnosisViewController *hvc = [[HypnosisViewController alloc] init];
TimeViewController *tvc = [[TimeViewController alloc] init];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
NSArray *viewControllers = [NSArray arrayWithObjects:hvc, tvc, nil];
[tabBarController setViewControllers:viewControllers];
[[self window] setRootViewController:tabBarController];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Regards
You haven't declared any titles or images for your TabBar items.
Use something like this: initWithTabBarSystemItem:tag:

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];

Set title and add button to navigation controller

I created a navigation controller but i can not set title or add button to the navigation bar.How to do that?
This is the code of application DidFinishLauchingOption in file AppDelegate.m :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:view];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
self.view = [[ViewController alloc] init];
self.window.rootViewController = self.view;
[self.window addSubview:navController.view];
[self.window makeKeyAndVisible];
return YES;
}
Thanks in advance.
You need to set the rootViewController property of your window object to the navigation controller, rather than your instance of `ViewController. This should point you in the right direction:
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Create and configure a window
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
// Create a view controller
UIViewController *viewController = [[ViewController alloc] init];
// Create a navigation controller and set its root view controller to the instance of `ViewController`
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
// Add the navigation controller to the window
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
// ...
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Set the view controller's title
self.title = NSLocalizedString(#"View Controller", #"");
// Add a navigation bar button
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:#selector(refreshButtonPressed:)];
}
- (void)refreshButtonPressed:(id)sender
{
// Do something when the refresh button is pressed.
}
// ...
#end
To create your initial setup, you create a navigation controller with your view controller and set it as the root view controller of your app delegate window:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//create window
[self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]];
//create and set root view controller
[[self window] setRootViewController:[[UINavigationController alloc] initWithRootViewController:[[RootViewController alloc] init]]];
//make window key and visible
[self.window makeKeyAndVisible];
//bail
return YES;
}
Then in your view controller, set the title and add your navigation item:
- (void)viewWillAppear:(BOOL)animated
{
//call parent implementation
[super viewWillAppear:animated];
//set view controller title
[self setTitle:#"Root View Controller"];
//add navigation bar button
[[self navigationItem] setRightBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:#"Button Title" style:UIBarButtonItemStyleBordered target:self action:#selector(handleBarButtonItemEvents:)]];
}
And listen for button events via:
- (void)handleBarButtonItemEvents:(id)sender
{
//
}

NavigationBar not displaying properling when pushViewController

The problem is pretty simple to understand with pictures.
I have a UINavigationController that allow the user to switch between to views.
The first view contains a search bar and a table view like so :
The second is a basic view where information about the cell are display
When I click on the search bar, the navigation controller gets hidden and the search bar is now at the top.
Now, if I click on a cell, it goes to the second views, but the navigation bar is first hidden like below :
And then, it automatically appears like that :
I have tried a couple of things like show the navigation bar before pushing the next view controller but it is quite ugly..
Does anyone know how to have the show the navigation bar directly on the second view (like in the contact application)?
[UPDATE] : Code
AppDelegate.m (I'm talking about navigationcontroller2)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
FirstViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
SecondViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
viewController1.managedObjectContext = [self managedObjectContext];
viewController2.managedObjectContext = [self managedObjectContext];
viewController1.viewController2 = viewController2;
UINavigationController *navigationcontroller1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
[navigationcontroller1.navigationBar setTintColor:[UIColor lightGrayColor]];
UINavigationController *navigationcontroller2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
[navigationcontroller2.navigationBar setTintColor:[UIColor lightGrayColor]];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:navigationcontroller1, navigationcontroller2, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
FirstView.m
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!noResultsToDisplay) {
PinDetailsViewController *pinDetailsViewController = [[PinDetailsViewController alloc] initWithNibName:#"PinDetailsViewController" bundle:nil];
NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
Pin *pin = (Pin *) managedObject;
[self.navigationItem setTitle:#"Pins"];
[self.navigationController pushViewController:pinDetailsViewController animated:YES];
[pinDetailsViewController updateWithPin:pin];
}
}
If you need anything else, just ask but I think it's all there.
Try to use this code in each viewcontroller.
- (void) viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
- (void) viewWillDisappear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
Before you push the new view controller, you should unhide the navigation bar:
[self.navigationController setNavigationBarHidden:NO animated:YES];
I had a similar problem with the position of my navbar. Mine was moving up behind the status bar, and I fixed the issue by manually setting the navbar frame:
-(void)adjustNavBarOrigin
{
CGRect r = self.navigationController.navigationBar.frame;
r.origin = CGPointMake(0, 20); // 20 is the height of the status bar
self.navigationController.navigationBar.frame = r;
}
I had to call this method in a number of places, including viewWillAppear: and didRotateFromInterfaceOrientation:, but it worked a treat :)
Hiding the UINavigationBar can disturb the properties sometimes. Try using the property alpha instead of hidden.

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];