I have posted similar question previously, but this time I am providing some code for analysis. I am creating PopOverController in my AppDelegate.m file and I am adding a NavigationController variable which I want to pass to PopOverController.m file so that using that I want to push other views. Here is how I am creating the PopOver in AppDelegate.m
- (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 *popoverContentController = [[PopOverViewController alloc]init];
UINavigationController *navcon = [[UINavigationController alloc]initWithRootViewController:popoverContentController];
popoverContentController.contentSizeForViewInPopover = CGSizeMake(250, 85);
popover = [[UIPopoverController alloc]initWithContentViewController:popoverContentController];
NSLog(#"X:%f Y:%f",buttonFrame.origin.x,buttonFrame.origin.y);
[popover presentPopoverFromRect:buttonFrame inView:self.tabBarController.tabBar permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
}
And in my PopOverController.m I am trying to use the NavigationController to choose views like this:
- (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.navigationController pushViewController:sendEmailViewController animated:YES];
else
[self.navigationController pushViewController:downloadFilelViewController animated:YES];
}
But when I click on my TabBar item for the PopOver I am getting this SIGABRT message :
Terminating app due to uncaught exception 'NSGenericException', reason: 'The content view controller argument must be the root of its associated view controller hierarchy.'
Any reason why this is appearing? Is there somewhere I am making a mistake in my code ?
UINavigationController *navcon = [[UINavigationController alloc] initWithRootViewController:popoverContentController];
you are trying to put a popover controller in a navigation controller. I don't think you want this.
To put navigation in popover, you should do this,
UINavigationController *navcon = [[UINavigationController alloc] initWithRootViewController:myViewController];
popoverContentController = [UIPopoverController initWithContentViewController:navcon]
and init the navigation controller with the viewController you want, like TableViewController or something else.
Related
In My Application I Build Every Thing Dynamic And I Doesn't Use Storyboard .
I Cannot push view controller when i pressed in cell
This is My Code .
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
TripDetailView * TripDetailViewObjec = [[TripDetailView alloc]init];
[self.navigationController pushViewController:TripDetailViewObjec animated:YES];
}
what i can do in this problem?
thanks in advance
In Your App Delegate, first create a navigation controller and push your table view controller on it like this
UITableViewController *tvc = [[UITableViewController alloc] init]; // your tableViewController
UINavigationController *nav = [UINavigationController alloc] initWithRootViewController:tvc];
[tvc release];
self.window.rootViewController = nav;
[nav release];
than your navigation controller wont be null and you can push new View Controller on It, like this!
TripDetailView * TripDetailViewObjec = [[TripDetailView alloc]init];
[self.navigationController pushViewController:TripDetailViewObjec animated:YES];
I have a tabbar in my project and each tab bar has a tableview.
I want to open a detail screen when click a row in a tableview as follows. But nothing happens.
Where's the mistake I'm doing. How should I set up a logic.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailScreen *detail = [[DetailScreen alloc] initWithNibName:#"DetailScreen" bundle:nil];
[self.navigationController pushViewController:detail animated:YES];
[detail release];
}
There are many possible reasons nothing is happening when you click on a cell.
Put a break point in this method. Is It even being called?
After the App has stopped at the breakpoint, go to the console type po detail after the instance is initialised. Make sure it's not (null)
Also try typing po [self navigationController] to check whether the navigation controller exists.
You've probably not got a navigation controller. How are you creating the tabbarcontroller? in interface builder or through code in the AppDelegate's didFinishLaunchingWithOptions: method?
Have you done this?
YourViewController *yourVC = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:yourVC];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:navigationController, nil];
try this,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailScreen *detail = [[DetailScreen alloc] init];
[self.navigationController pushViewController:detail animated:YES];
[detail release];
}
I guess you don't have a navigation controller so
[self.navigationController pushViewController:detail animated:YES];
will not work.
use
[self.view addSubview:detail.view]
or
[self presentModalViewController:detail animated:YES];
instead
If your project is UITabBarViewController based application, i dont think your can navigate to another view using pushViewController unless you have navigationController in your project.
Add your view controller(your table view containing controller) into navigation controller and then start using
DetailScreen *detail = [[DetailScreen alloc] initWithNibName:#"DetailScreen" bundle:nil];
[self.navigationController pushViewController:detail animated:YES];
[self.navigationController pushViewController:detail animated:YES];
Instead move your detail push code to another method and call:
[self performSelector:#selector(myMethod:) withObject:nil]
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.
I present a modalViewController that is actually a navigation controller with one view, and a custom navigation bar. The modal view appears fine as expected, but when I attempt to remove it from view using [self dismissModalViewControllerAnimated:YES], I am hitting a "-[UINavigationController modalViewController]: message sent to deallocated instance". Can't seem to figure this out. Any ideas?
Instantiating the ModalViewController:
// Make a navigation controller and add the view inside it
MyViewController *evc=[[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
//UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:evc];
UINib *nib = [UINib nibWithNibName:#"UINavigationBarWithBackgroundImage" bundle:nil];
UINavigationController *nvc = [[nib instantiateWithOwner:nil options:nil] objectAtIndex:0];
[nvc setViewControllers:[NSArray arrayWithObject:evc]];
evc.delegate=self;
[evc release];
[self presentModalViewController:nvc animated:YES];
[nvc release];
and trying to remove it. This is where the error comes in:
[self dismissModalViewControllerAnimated:YES];
Not sure about this, but try it anyway:
Remove
[nvc release]
and see if
[self dismissModalViewControllerAnimated:YES];
now works.
Is there a reason you are loading two seperate nibs to show this modal? You do not need to load a nib containing a navigation controller to get this working.
Try something like this:
// Make a navigation controller and add the view inside it
MyViewController *evc= [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:evc];
evc.delegate=self;
[self presentModalViewController:navController animated:YES];
[evc release];
[navController release];
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];