I have TabBarView Controller, where i keep four tab bar items, let sat item1, item2, item3 and item 4.
When clicking on item2 tab bar item, i call a RootViewController where it has a Navigation controller with a TableView and shows the row items.
Upto here it is fine.
When clicking on a row item, will have to launch a UIWebView to show the content.
I did code like below for this process.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
navigationController = [[UINavigationController alloc] init];
webViewController = [[WebViewController alloc] init];
[[self navigationController] pushViewController:webViewController animated:NO];
[webViewController release];
}
The problem now is, clicking on a row item is not pushing the UIWebView code at all. I tested the UIWebView code with normal addSubView method like
"[appDelegate.window addSubview:webViewController.view];"
instead of calling via pushViewController. It is calling UIWebView and shows the web content successfully.
I understand the problem should be calling as pushViewController:webViewController.
Can anyone point me what are the ways that it should be not be worked in this case and how can i correct it to make it work with pushViewController itself? I need to call UIWebView only using pushViewController.
For such all these combination, is there any sample source available?
Waiting for someone's help.
thanks.
Clave/
I think you are mistakenly creating a new navigation controller here
navigationController = [[UINavigationController alloc] init];
remove that line and use
[self.navigationController pushViewController:webViewController animated:NO];
instead of your reference above. That should do it :-)
Related
I have a ViewBased App. I added a UITableView on one of the UIViewControllers. It shows the data and I implemented all the delegate methods etc. My problem is when I want to show the detailView it just doesn't happen. My code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *detailViewController =[[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
NSLog(#"DidSelectRowAtIndexPath");
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
I see that I need a navigationController but I don't have one and I was unsucessful trying to add one programatically. I don't have one in my appDelegate either, so my question is do I need to add one to show the detail view? If yes, please give me a code sample how to do that.
If not, what other way is there?
I am new to iOS so I am a bit lost here.
Please help!
To add a navigation controller programmatically just for this detail view, you need to something like this:
UINavigationController * controller = [[UINavigationController alloc] initWithRootViewController:detailViewController];
[[detailViewController] release];
[self presentModalViewController: controller animated: YES];
If you want to use pushViewController, you need to already have a navigation controller surrounding the view you're starting with.
You need to add the Navigation Controller FIRST, then your master table becomes the root view controller of the nav controller, then when you tap a row in the table, you push another view controller onto the nav stack.
How does your master table get into the app in the first place? If you're using a nib, it's super easy to just change out the view controller for a nav controller with the old view controller added as a child of the nav controller.
You can create one programmatically by working within your app delegate's application:didFinishLaunchingWithOptions: method like so:
UITableViewController *tableViewController = [[[WhateverYourSubclassVCIsCalled alloc] init] autorelease];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
window.rootViewController = navController;
[window makeKeyAndVisible];
There are actually three views at play. My homeView, which is where I launch the picker from, which sets the StudyPickerController view as root to a navController, which is then presented inside of the popOverController. Then from within the StudyPickerController view, I need to push to the ScreenPickerController, a different view completely.
I have a UIPopOverController that is displaying the contents of a view that is a tableView. I would like to be able to push a new view with a viewController inside of this view, but as I will discuss, it is really close, but it just won't push!
So from my homeView, when the button is pushed, an action is called and this code is run:
self.studyPicker = [[[StudyPickerController alloc] initWithStudyArray:self.studyArray ViewNum:butto.tag] autorelease];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.studyPicker];
_studyPicker.delegate = self;
self.studyPickerPopover = [[[UIPopoverController alloc] initWithContentViewController:navController] autorelease];
[self.studyPickerPopover presentPopoverFromRect:CGRectMake(120,45, 10,10) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
And this works pretty well! The popOverController displays the contents of my StudyPickerController without any problems. I get the feeling that I am indeed getting access to my navigationController because the frame of the popOverController has a bar at the top, instead of just being a thin border, it has a navigationBar.
So now when I want to select a row in this view, I would like to push to a new view, also with a tableView, with my navigationController. This is the code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray * array = [_studyArray objectAtIndex:indexPath.row];
ScreenPickerController * picker = [[ScreenPickerController alloc] init];
picker.seriesGUID = array;
picker.viewNumber = viewNumber;
[self.navigationController pushViewController:picker animated:YES];
}
It seems to me that this should be working! But alas, I press a row, and it highlights, and nothing happens.
I've been working on this all day, so it very well could be that I am just missing something, but I don't know what it is. Any help is appreciated
It seems there are two classes involved here: your homeView class and the StudyPickerController. I'm guessing the tableView:didSelectRowAtIndexPath: method would be in the homeView class?
In that case, self.navigationController is trying to access the navigation controller that homeView is in, not the navigation controller you put into the popover. Since homeView isn't even in a navigation controller, the accessor returns nil.
Instead, you will want to use something like [self.studyPicker.navigationController pushViewController:picker animated:YES];.
First of all I know this is a long question. REST ASSURED I have tried to figure it out on my own (see: StackOverflow #2609318). This is driving me BATTY!
After trying and failing to implement my own EDIT feature in the standard moreNavigationController, I have decided to re-implement my own MORE feature.
I did the following:
Add a HOME view controller which I init with: initWithRootViewController
Add 3 other default tabs with:
ResortsListViewController *resortsListViewController;
resortsListViewController = [[ResortsListViewController alloc] initWithNibName:#"ResortsListView" bundle:nil];
resortsListViewController.title = [categoriesDictionary objectForKey:#"category_name"];
resortsListViewController.tabBarItem.image = [UIImage imageNamed:#"whatever.png"];
resortsListViewController.navigationItem.title=#"whatever title";
localNavigationController = [[UINavigationController alloc] initWithRootViewController:resortsListViewController];
localNavigationController.navigationBar.barStyle = UIBarStyleBlack;
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[resortsListViewController release];
Those work when i add them to the tabbar. (ie: click on them and it goes to the view controller)
Then I add my own MORE view controller to the tabbar:
MoreViewController *moreViewController;
moreViewController = [[MoreViewController alloc] initWithNibName:#"MoreView" bundle:nil];
moreViewController.title = #"More";
moreViewController.tabBarItem.image = [UIImage imageNamed:#"more.png"];
moreViewController.navigationItem.title=#"More Categories";
localNavigationController = [[UINavigationController alloc] initWithRootViewController:moreViewController];
localNavigationController.navigationBar.barStyle = UIBarStyleBlack;
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[moreViewController release];
Then
tabBarController.viewControllers = localControllersArray;
tabBarController.moreNavigationController.navigationBar.barStyle = UIBarStyleBlack;
tabBarController.customizableViewControllers = [NSArray arrayWithObjects:nil];
tabBarController.delegate = self;
That creates the necessary linkages. Okay, so far all is well. I get a HOME tab, 3 category tabs and a customized MORE tab -- which all work.
in the MORE tab view controller I implement a simple table view that displays all the other tabs I have in rows. SINCE I want to be able to switch them in and out of the tabbar I created them JUST like i did the resortslistviewcontroller above (ie: as view controllers in an array). When I pull them out to display the title in the tableview (so the user can go to that "view") i simply do the following:
// [myGizmoClass CategoryArray] holds the array of view controller tab bar items that are NOT shown on the main screen.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
... etc...
UIViewController *Uivc = [[myGizmoClass plusCategoryArray] objectAtIndex:indexPath.row];
cell.textLabel.text = [Uivc title];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
THIS is where it falls through:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MyGizmoClass *myGizmoClass= [MyGizmoClass sharedManager];
UIViewController *tbi = [[myGizmoClass plusCategoryArray] objectAtIndex:indexPath.row];
NSLog(#"%#\n",[[tbi navigationItem ]title]);
[self.navigationController pushViewController:tbi animated:YES];
}
This is the error i get ("ATMs" is the title for the clicked tableview cell) so i know the Uivc title is pulling the correct title and therefore the correct "objectatindex":
2010-04-09 11:25:48.222
MouseAddict[47485:207] ATMs 2010-04-09
11:25:48.222 MouseAddict[47485:207]
*** Terminating app due to uncaught exception
'NSInvalidArgumentException', reason:
'Pushing a navigation controller is
not supported'
BIG QUESTION: How do i make the associated VIEW of the UIViewController *tbi show and get pushed into view?
I am GUESSING that the UIViewController is the correct class for this tbl .. i am not sure. BUT i just wanna get the view so i can push it onto the stack.
Can someone plz help?
To answer kovpas's question below: myGizmoClass is a singleton (apple's singleton myGizmo class. The array of viewcontrollers is stored in that just like it is in [localControllersArray addObject:localNavigationController]; (in the first code snippet above). AND it does put it in and pull it out correctly as evidenced by the fact that when i NSLOG the [Uivc title] the log prints ATMs. This means the plusCategoryArray is correctly storing and retrieving the viewController (if, indeed, that is what is being stored).
Pushing a navigation controller is not supported is really bothering me. Why would a viewController return a navigationController and is it possible to coerce the navigationController to get the "pushable" view out of it... or does the navigationController have some element in it that is the view?
From the error, it looks as if your Gizmo class has an array of UINavigationControllers, not UIViewControllers. So instead push with:
[self.navigationController pushViewController:[[tbi viewControllers] lastObject] animated:YES];
If the array is the same array as you called localControllers above, then this should work better. Or you could just create the array without the UINavigationControllers, they aren't needed if you are going to push them onto your more controller navigation controller.
I'm not sure, but it looks like this error appears when you are trying to push UINavigationController into another UINavigationController. Could you please provide an implementation of MyGizmoClass?
I have an application that has a tabBar that handles all the views. In the first view I have a login process. When that process finishes I want to go automatically to the second tabBar view without making the user to click in its respective tabBar button.
All I've got until now is to highlight the button with this:
myTabBar.selectedItem = [myTabBar.items objectAtIndex:1];
But I have no idea about how to bring the second view related to that button to the front, automatically. Until now the user has to press the button when it gets lighted (selected).
Any idea about how to do this? Is it possible? It would be much appreciated. Thanks.
Use the selectedViewController or selectedIndex methods of the corresponding UITabBarController.
In response to the comments on this answer, I have provided an example of how this might be accomplished:
id firstViewController = [[FirstViewController alloc] initWithNibName:#"FirstView" bundle:[NSBundle mainBundle]];
id secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondView" bundle:[NSBundle mainBundle]];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:firstViewController, secondViewController, nil];
[firstViewController release];
[secondViewController release];
// Select the second tab bar item and its view
self.tabBarController.selectedIndex = 1;
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
In my testing, it seems that using the selectedViewController method of UITabBarController to set the current view does not update the selectedIndex property (the new view is displayed but the selected UITabBarItem is not changed). This is in contrast to the behavior promised in the documentation. Using the selectedIndex method as demonstrated in the code snippet above should work fine, however.
you should implement the UITabBarControllerDelegate protocol, as explained here: http://developer.apple.com/library/ios/#documentation/uikit/reference/UITabBarControllerDelegate_Protocol/Reference/Reference.html
to change the active tab, use tabBarController:shouldSelectViewController:
As explained in the documentation "You can use this method to dynamically decide whether a given tab should be made the active tab."
Finally I got the solution here:
iphone sdk: set focus to different tabbar view on button click from first tabbar item
Thanks anyways.
I have a Navigation-Based Application that shows a TableView where you can select a cell and it brings you to a "Detail View" for that cell. I want this view to then have a TabBar where I can select between 3 subviews. I have found several solutions online for this but none are very helpful. Is there a tutorial for this specifically or is their source code indicating how it can be done? Thanks
Basically What you need to do is push a Tab View Controller onto the Navigation Controller's viewcontroller stack.
Starting with a fresh "Navigation-Based Application" template. I added the following method in RootViewController.m :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Navigation logic may go here. Create and push another view controller.
UIViewController *viewOneViewController = [[UIViewController alloc] init];
viewOneViewController.title = #"One";
viewOneViewController.view.backgroundColor = [UIColor redColor];
UIViewController *viewTwoViewController = [[UIViewController alloc] init];
viewTwoViewController.title = #"Two";
viewTwoViewController.view.backgroundColor = [UIColor orangeColor];
UIViewController *viewThreeViewController = [[UIViewController alloc] init];
viewThreeViewController.title = #"Three";
viewThreeViewController.view.backgroundColor = [UIColor greenColor];
UITabBarController *anotherViewController = [[UITabBarController alloc] init];
anotherViewController.viewControllers = [NSArray arrayWithObjects:viewOneViewController, viewTwoViewController, viewThreeViewController, nil];
[self.navigationController pushViewController:anotherViewController animated:YES];
[anotherViewController release];
}
Changed this to 25 to test:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 25;
}
Now when I build and run I'll see what you are looking for in a basic way. What you will want to do after you get this working is to change the UIViewControllers to Custom Subclasses that you create to hold the code for each view. (If you are also using Interface Builder, change the init to initWithNibNamed:).
Hope this helps you get on your way a bit.
You should be aware that it's possible Apple will reject your application if you do this though.
From "Combining Tab Bar and Navigation Controllers"
It’s very common to combine tab bar and navigation controllers, as illustrated in Figure 4. To do this, you simply add navigation controllers to a tab bar controller (however, you should never add a tab bar controller to a navigation controller).
So it's likely to be against the Human Interface guidelines and so could you get rejected.
I'm trying to do this very same thing. The application "Tweetie" is doing something similar. They have a TableView of accounts and then you select an account and TabBar appears.
Anyways, straight from Apple's Documentation:
pushViewController:animated:
Pushes a view controller onto the receiver’s stack and updates the display.
(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
Parameters
viewController
The view controller that is pushed onto the stack. It cannot be an instance of tab bar controller. This method does nothing if the view controller is already on the stack.
animated
Set this value to YES to animate the transition. Pass NO if you are setting up a navigation controller before its view is displayed.
So maybe we're just stuck using a TabBar and not a TabBarController?
-JP