Can anyone tell me if this is possible?
I have a setup a UITableViewController which consists of a number of cells, if you select one of these cells you are taken to a new viewController using pushViewController (see below)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
NSLog(#"CELL__: You tapped the row ... %#", [list objectAtIndex:row]);
TestController *testController = [[TestController alloc] init];
[[self navigationController] pushViewController:testController animated:YES];
[testController release];
}
If in the implementation for "TestController" I would like to refer back to [self navigationController] (or maybe to add yet another view) is there any way to do that. My problem is that I need to access [self navigationController] to push further views and I don't know how to do that from the bottom controller?
Does that make sense?
Gary
From within TestController you reference the same UINavigationController via [self navigationController] as well.
EDIT to elaborate after comment:
The navigationController property is a property of UIViewController. If the controller is contained within a UINavigationController then it's own navigationController property will be a reference to that container UINavigationController. The same applies for tabBarController and splitViewController.
Related
I followed this great tutorial on a slide out menu using UIKit Dynamics, Slide Out Menu. The code has been slightly modified to reduce duplication of code. I'm handling the touch event in the MenuComponent Class. Now, I'm trying to move to another view controller when the item is selected. The menu is created in code so I can't use segue's.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[[tableView cellForRowAtIndexPath:indexPath] setSelected:NO];
[self toggleMenu];
self.isMenuShown = NO;
if(indexPath.row == 0){
//move to the testViewController
}
How do you remove the current view and present a new one? My hierarchy is a navigation controller then my testViewController.
Edit: I did find this code which I tried, but my problem is the when the menu is present and I try to present the view I get an error:
testViewController *test = (testViewController*)[storyboard instantiateViewControllerWithIdentifier:#"testViewController"];
[self presentViewController:test animated:YES completion:nil];
Warning: Attempt to present <testViewController: 0x7c095470> on <MenuComponent: 0x7ae4ce50> whose view is not in the window hierarchy!
I was able to figure it out by creating a delegate for the MenuComponent and then pass the view like so:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController * test = [storyboard instantiateViewControllerWithIdentifier:#"test"] ;
[delegate didCallViewController:test];
I have the right view selected from my PopOver but instead of showing in Parent View it is showing in PopOverView.
Here are some screenshots:
After I select the Feedback option instead showing the view in my parentview which in my case is SecondViewController (grey background screen) it is showing in the PopOver itself.
For information I have Three VC's namely FirstViewController, SecondViewController and ThirdViewController each assigned to each TabBar item. I want to make SecondViewController as parent for the PopOver.
Here is my code where I create PopOver in my 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:navcon];
NSLog(#"X:%f Y:%f",buttonFrame.origin.x,buttonFrame.origin.y);
[popover presentPopoverFromRect:buttonFrame inView:self.tabBarController.tabBar permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
}
And the code in my PopOverController.m where I am making a choice of which new view to show
- (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];
}
Can anyone let me know how I can make the reference to my parent view (SecondViewcontroller) so that the new view shows in my parent view rather than the popover view.
Thanks
You insert into popover UINavigationController and in didSelectRowAtIndexPath push newly created controller to existed stack (into popover UINavigationController), but not into tab bar.
In order to push newly created controller to second tab you need to assign second tab (now it is SecondViewController) to new UINavigationController and use exactly this navigation stack.
Code will look like this:
UINavigationController *navController = (UINavigationController*)[tabBarController.viewControllers objectAtIndex:1];
[navController pushViewController:downloadFilelViewController animated:YES];
At the moment, I have an iOS app that starts out with a NavigationView (root view) and a table contained in the root view below the navigation bar. I am attempting to load another view (hoping to make it another table) from a .nib file when the first row in the original table is selected. How can I do this?
Any help or advice would be appreciated. Thank you very much.
You need to make use of the UITableViewDelegate method, tableView:didSelectRowAtIndexPath:
Ensure that your tableview's delegate is set to your view controller inside Interface Builder, or if you are not using interface builder..
[tableView setDelegate:self];
Your view controller will then adopt the UITableViewDelegate protocol and respond to tableView:didSelectRowAtIndexPath: when a row is selected.
Loading your new view when the first row is selected will be implemented like so..
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.section == 0){ // the first row
MyView *myView = [[MyView alloc] init];
[self.navigationController pushViewController:myView animated:YES];
[myView release];
}
}
My RootViewController is a UITableViewController. A UINavigationController is added programmatically:
_navigationController = [[[UINavigationController alloc] initWithRootViewController:_rootViewController] autorelease];
[self.window addSubview:_navigationController.view];
[self.window makeKeyAndVisible];
Within the RootViewController.m the DetailViewController should be loaded when a row is selected:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Switch to detail");
CCouchDBDocument *selectedObject = [self.contentsList objectAtIndex:indexPath.row];
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
[self.view addSubview:detailViewController.view];
[detailViewController setDetailItem: selectedObject];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
Without addSubView nothing happens on the screen. All the examples I've seen before only use pushViewController. And, loading the DetailView takes about 4 seconds. That's way too long (it's currently empty, just one label). When I try to set the navigationTitle (self.title = #"Hello";), the title remains the same from the RootViewController, so something must be wrong with the navigationController.
I tried to put everything in the AppDelegate and use a switchView method. The problem is the call for setDetailItem, which I can't call if I work with the switch method.
What would be the correct way to load the DetailView from the RootViewController into the navigation stack and possibly more from the DetailViewController later?
Update
I started from the beginning again with a Window-based application. Added a UITableViewController as "RootViewController" and initialised it with the UINavigationController in the AppDelegate (did absolutely nothing in the XIB). When I try to set self.navigationController.title = #"Test"; in ViewDidLoad, nothing happens.
What's wrong there?
You don't set the title of the DetailView when it's displayed using a UINavigationController by using self.title, you need to set the UINavigationItem title property in the DetailView initializer.
e.g. in the DetailView initializer :-
self.navigationItem.title = #"Hello";
You're right you shouldn't need to add the detailViewController view as a subview of the current view - you should just need the pushViewController call. I'm not sure why it's not appearing though.
Obvious questions are is everything connected OK in the nib, and what does the DetailView initializer do?
I'm following Apple sample code "MultipleDetailViews" but what I want to do is that:
at start, shows the RootViewController (table view) display the default detailViewController (1st detailView)
when user selected a table cell, push into the stack, display the SubCategoriesVC (table view) in the master of the splitView but don't update the detailView.
in SubCategoriesVC, selecting a table cell.. update the detailViewController (2nd detailView)
So, in RootViewController.m, I push another navigation
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SubCatVC *browseSubCatView = [[SubCatVC alloc] initWithNibName:#"SubCatVC" bundle:nil];
[self.navigationController pushViewController:browseSubCatView animated:YES];
[browseSubCatView release];
}
Then, in SubCatVC.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
SecondDetailViewController *newDetailViewController = [[SecondDetailViewController alloc] initWithNibName:#"SecondDetailViewController" bundle:nil];
detailViewController = newDetailViewController;
// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
self.splitViewController.viewControllers = viewControllers;
[viewControllers release];
// Dismiss the popover if it's present.
if (self.popoverController != nil) {
[self.popoverController dismissPopoverAnimated:YES];
}
// Configure the new view controller's popover button (after the view has been displayed and its toolbar/navigation bar has been created).
if (self.rootPopoverButtonItem != nil) {
[detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
}
[detailViewController release];
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateProduct" object:nil];
}
but it didn't update my detailView.. so I don't know what's wrong?
Src here: http://pastebin.com/iy6SqLqt
Hope someone can advise me. Thanks
I Have not looked at your source, but but a common problem with Split views are delegates.
When you Push a new rootController ont the nav stack, you need to make sure it has the pointer to the detailViewController that you want it to talk to. You can check htis my logging the delegate before you try to update it:
In your SubCatVC (or any root for that matter):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//do stuff, init alloc vc's....
NSLog(#"DELEGATE: %#",self.delegate);
//push/delegate etc..
}
If you find its nil, copy the original roots delegate, or when your putting your new detail in, notify/set the root you want to comunicate with it.
If you need any more detail, just ask.