Folks,
New to iPhone development so I greatly appreciate your help. I have been looking at documentation and trying many things to get my navigation controller functionality working but can't.
Here's the situation. I have an app delegate which sets its root controller to be a navigation controller:
- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window.rootViewController = self.mainViewController.navController;
[self.window makeKeyAndVisible];
return YES;
}
The navigation controller is a property of the mainviewcontroller because I intend to take the user to a map view (associated with a mapviewcontroller) only when they select an item in a tableview owned by mainviewcontroller. I can't yet think of a graceful way to notify the appdelegate about a table row selection, hence I am trying to handle this in the mainviewcontroller.
In the mainviewcontroller init function:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
// Custom initialization
navController = [[UINavigationController alloc] initWithRootViewController:self];
mapController = [[MapViewController alloc] init];
}
return self;
}
In mainview controller, when the user selects an item from the tableview, I call:
[self.navController pushViewController:mapController animated:YES];
The view associated with my mapviewcontroller never appears. Any ideas what's going on?
Thanks
Add this
[self.window addSubview:self.mainViewController.navController.view];
Before
[self.window makeKeyAndVisible];
Related
I have page-based app. On each page I have 3 uibuttons at the top, uiscrollview with alphabet (uibuttons to sort data in uitable) at the right and uitableview at the center. How to show cell's detail view? If it is necessary to add uinavigationcontroller I can't do this. If I adds it, it disables interaction with my table, buttons and scrollview.
And another question is how to show new data in tableview and scrollview when goes to next page??
I have rootViewController class and DataViewController class.
rootViewController listing:
#interface RootViewController ()
#property (readonly, strong, nonatomic) ModelController *modelController;
#end
#implementation RootViewController
#synthesize pageViewController = _pageViewController;
#synthesize modelController = _modelController;
#synthesize navContr = _navContr;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Configure the page view controller and add it as a child view controller.
//[self presentModalViewController:navContr animated:YES];
self.pageViewController = [[[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil] autorelease];
self.pageViewController.delegate = self;
DataViewController *startingViewController = [self.modelController viewControllerAtIndex:0 storyboard:self.storyboard];
NSArray *viewControllers = [NSArray arrayWithObject:startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL];
self.pageViewController.dataSource = self.modelController;
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
self.navContr = [[UINavigationController alloc] initWithRootViewController:self.pageViewController];
[self.view addSubview:self.navContr.view];
// Set the page view controller's bounds using an inset rect so that self's view is visible around the edges of the pages.
CGRect pageViewRect = self.view.bounds;
self.pageViewController.view.frame = pageViewRect;
[self.pageViewController didMoveToParentViewController:self];
// Add the page view controller's gesture recognizers to the book view controller's view so that the gestures are started more easily.
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
for (UIGestureRecognizer *recognizer in self.pageViewController.gestureRecognizers){
if ([recognizer isKindOfClass:[UITapGestureRecognizer class]]){
[recognizer setEnabled:NO];
}
}
}
After few manipulations it works but I need help to get it work fine!
So now it looks like this
Next question: how do I remove the brown space at the top???
::UPDATE::
Problem solved. It needs just to set y-axis position of UINavigationController to -20 ;)
i'm not sure if this link about creating navigation-based project may help you.. (http://iosmadesimple.blogspot.com/2012/08/navigation-based-project-doing-it.html)
From that tutorial, there's a class called SampleViewController, subclass of UIViewController. You might want to put a tableView in SampleViewController.xib file. Then in your SampleViewController.h file, add an IBOutlet UITableView* yourTable property and synthesize it. Connect it to your tableView in your .xib file. //Or you may do it programmatically
in your SampleViewController.h, make your interface header look like this.. I think you already know this...
#interface SampleViewController:UIViewController < UITableviewDelegate, UITableViewDatasource >
in your SampleViewcontroller.m, under viewDidLoad method, set the table delegate and datasource to self:
yourTableView.delegate = self;
yourTableView.datasource = self;
Afterwhich, you implement tableView delegate and datasource methods... //you already know those since you were already able to show a tableview ;)
one of these methods is the "tableview:didSelectAtIndexpath:" --> this is the part wherein you can put your code when you click one of the cells.
Let's assume you have the DetailsViewController Class, this is the class you would like to show after clicking a cell and show its details.
DetailsViewController Class must have a variable that will accept the data you would like to show. Let's say, an NSString *detailsMessage; //do the #property and #synthesize thing...
Let's go back to SampleViewController.m file, under tableview:didSelectAtIndexpath: Method:
inside that Method.. put these codes.
DetailsViewController *detailsVC = [[DetailsViewController alloc] init];
detailsVC.detailsMessage = #"The Data you want to pass.";
[self.navigationController pushViewController:detailsVC animated:YES];
I hope this helps. :(
There may be other ways but by far the easiest way is to use a navigation controller. In fact, it is built to do exactly this.
If you don't want the navigationBar then you can hide it in the viewWillAppear function.
[self.navigationController setNavigationBarHidden:YES animated:YES];
Then you can add an other UIViewController to push when the user selects a cell.
Having read your OP again I'm not sure how you are adding your navigationController.
To use a navigationController you create it and load it at start time. You then create your current viewController (the one with the buttons and table etc...) and set this as the rootViewController of the navigationController.
Then you display the navigationController.
Could you explain how you are adding your navigationController as it may help understand what is going wrong.
Thanks
::EDIT::
OK, my assumption was correct.
The way you are using the navigation controller is not how it was intended.
OK, so at the moment your AppDelegate file will have a method Application didFinishLaunching...
It will look something like this...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[OJFViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
You should change it so that it is like this...
first add a property to your appDelegate...
#property (nonatomic, strong) UINavigationController *navigationController;
Then change the didFinishLaunchingMethod to this...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[OJFViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
This will still show you MainViewController but it will now be contained within a navigationController.
Next in your MainViewController function viewWillAppearAnimated add the line...
[self.navigationController setNavigationBarHidden:YES animated:animated];
This will then hide the navigationBar at the top of the view so you still have access to your buttons.
The you need a new ViewController and xib file (for example DetailViewController).
When the user selects a table row you need to then do something like...
DetailViewController *detailView = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
//pass in details of which row was selected.
[self.navigationController pushViewController:detailView animated:YES];
This will then display your new view and new viewController. You will also need to write a way of passing the data in (set up a property on the DetailViewController).
Hope this helps.
I'm having trouble coding a button to go to the previous page. I was able to do it to go to the next page thinking if I did the same thing but changed it a bit it would work in reverse. Unfortunately, I come up with a lot of errors I can't resolve because it won't allow me to use the release function.
This is this the code that helps it to work going to the next page fine:
#import "ViewController.h"
#implementation ViewController
-(IBAction)btnClicked:(id) sender
{
//add the view of the view controller to the current View---
if (menuView==nil) {
menuView =
[[MenuView alloc] initWithNibName:#"MenuView"
bundle:nil];
}
[self.view addSubview:menuView.view];
}
-(void)dealloc {
[menuView release];
[super dealloc];
}
How do I do it so that a back button will go to the previous page though.
It's pretty simple, use this :
-(IBAction)back:(id) sender
{
[menuView.view removeFromSuperview];
}
But, I would suggest not using addSubview: for many views as it would be complex way to do. Use UINavigationController as #Paul.s suggested.
The way you are doing this is not quite correct and I would suggest doing some reading to get familiar with iOS programming.
Your program structure should be: create a navigation controller (2) to manage the stack of view controllers giving it a viewController (1) to act as it's root.
// AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// 1
FirstViewController *firstViewController = [[FirstViewController alloc] init];
// 2
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
[firstViewController release]; firstViewController = nil;
self.window.rootViewController = navigationController;
[navigationController release]; navigationController = nil;
[self.window makeKeyAndVisible];
return YES;
}
This will display your first view controller inside a UINavigationController. A UINavigationController is responsible for managing a stack of UIViewController's and giving you UI to navigate back down the stack as well as calling all the appropriate presentation related methods on a UIViewController at the correct times e.g. viewDidLoad. You should check out The View Controller Programming Guide for lots of info
Then inside your first view controller you do something like this to respond to the button:
- (IBAction)buttonClicked:(id)sender;
{
SecondViewController *secondViewController = [[SecondViewController alloc] init];
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release]; secondViewController = nil;
}
This creates a new view controller and pushes it onto the stack.
I'm trying to display an "About Page" in my application when pressing a button, but when I press the UIButton, the NSLog(#"Button pressed") is called, but the view won't load. Here is my code:
- (IBAction)pushAbout {
NSLog(#"Button pressed");
AboutView * aboutView = [[AboutView alloc] initWithNibName:#"AboutView" bundle:nil];
[self.navigationController pushViewController:aboutView animated:YES];
[aboutView release];
}
I've seen this code in an example, but it was called in a UITableViewController instead of an ordianry UIView controller.
The class files "AboutView" were created as UIViewController subclass. They were created and left untouched
A guess: Your view is not in a UINavigationController, hence
self.navigationController
is actually nil, and nothing happens.
The solution would be to place the main view in a nav controller, and adding the nav controller's view to your application's main window.
A simple way of doing this:
In your app delegate, change
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
to
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions
(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UINavigationController* navController = [[UINavigationController alloc]
initWithRootViewController:self.viewController];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
Or similar. Note that this is just to get you started, and maybe not the nicest way of doing it. (I assumed you've just created a view-based application in xcode.)
Yes you don't have a UINavigationController set.
Add
NSLog(#"nav? %#", self.navigationController);
to your action and you'll see that it dumps (null).
However, the AboutView.xib works fine if you enter this code:
[self presentModalViewController:aboutView animated:YES];
instead of
[self.navigationController pushViewController:aboutView animated:YES];
The view will show up. In you zipped example the AboutView.xib didn't contain a label, so don't wonder if it turns out to be a white page.
You can dismiss the presented modal view by using
[self dismissModalViewControllerAnimated:YES];
in your AboutViewController.
To get your hands on a UINavigationController I suggest creating an app with the Navigation-Based Application template.
I have custom view controller named DRTableViewController
In my app delegate, I use the following function to load
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
tvc = [[DRTableViewController alloc] init]; // tvc is created with xib
navCon = [[UINavigationController alloc] initWithRootViewController:tvc];
[self.window addSubview:[navCon view]];
[navCon release];
[self.window makeKeyAndVisible];
return YES;
}
but when I start my application, navigation controller appears but the view inside it is black,
when I use
[self.window addSubview:[tvc view]];
instead of [navCon view]; I can see my view without any problem
Thanks in advance
You need to retain your navigation controller so it is not released.
Create a property for you navigation controller and retain it in the application delegate.
A quick fix is to comment out the line,
[navCon release]
But this will introduce a memory leak.
I am creating an application which I want to have a view controller with buttons as the first view controller with no navigation bar, and then when the user selects a button a table view controller appears managed by a navigation controller.
At the moment I am setting up the navigation controller in the app delegate and setting the top view controller as the table view controller I want to start the navigation bar on. So far I can see the navigation bar but that is it when I transition from the first view controller to the table view controller.
Any help would be much appreciated as I have confused myself with this issue.
I'm not totally clear on what you are asking, so I might have it wrong, but here goes.
The top navigation bar is can be displayed or hidden by calling:
self.navigationController.navigationBarHidden = NO;
In the viewWillAppear method of your viewController. So set it to YES or NO depending on whether or not you want it to be displayed.
#Disco, you would do something like so:
// In the App delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CustomViewController *viewController = [[CustomViewController alloc] init];
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
// In your button method
- (IBAction)loadUpTableViewController:(id)sender {
CustomTableViewController *tvc = [[CustomTableViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:tvc];
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[tvc release];
}