problems with didselectrowatindexpath - iphone

i have just converted an app i was making from a navigation controller app into a tab bar app.
an everything works fine apart from this one thing, the first of my tabs brings in a table view,and what i want to happen is when a user selects a cell i want it to push on a different view controller(like it did when it was a navigation app)
but this no longer seems to work, am i doing something silly
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
StoryDetailViewController *storyDetailViewController = [[StoryDetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
WorldCupAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
Story *aStory = [appDelegate.stories objectAtIndex:indexPath.row];
NSURL *url = [NSURL URLWithString:aStory.picture];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
storyDetailViewController.downloadedImage = img;
storyDetailViewController.story = [appDelegate.stories objectAtIndex:indexPath.row];
[self.navigationController pushViewController:storyDetailViewController animated:NO];
NSLog(#"view controller pushed");
[StoryDetailViewController release];
}

The problem is in self.navigationController. Since it's no longer part of a navigation controller, navigationController is nil. If you want to push new views onto the hierarchy, you can do so by creating a navigation controller with that view as its root view controller, and then adding the navigation controller's view to the tab bar instead.

Related

UIActivityIndicator in tableviewcell Showing Up Late when loading the detailview?

I have a tableview with responding detialview. In the detailview I have some images and labes that is loaded from a URL. I'm trying to add a UIActivityindicatorview to the cell to show that is loading. I have handled that but it shows up to late and does not disappear when I go back to the tableview. I have looked all over to find a simple solution, but failed...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ReaDetailViewController *reaDetail = [[ReaDetailViewController alloc] initWithNibName:#"ReaDetailViewController" bundle:nil];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIActivityIndicatorView *activityView =
[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[activityView startAnimating];
[cell setAccessoryView:activityView];
[activityView release];
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
{
reaDetail.petImageString = [[NSString alloc] initWithString:[[exclusiveArray objectAtIndex:indexPath.row] objectForKey:#"image"]];
reaDetail.petLabelString = [[NSString alloc] initWithString:[[exclusiveArray objectAtIndex:indexPath.row] objectForKey:#"description"]];
reaDetail.petLabelString1 = [[NSString alloc] initWithString:[[exclusiveArray objectAtIndex:indexPath.row] objectForKey:#"description1"]];
reaDetail.petLabelString2 = [[NSString alloc] initWithString:[[exclusiveArray objectAtIndex:indexPath.row] objectForKey:#"description2"]];
reaDetail.title = [[exclusiveArray objectAtIndex:indexPath.row] objectForKey:#"name"];
}
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:reaDetail animated:YES];
[reaDetail release];
}
Any help is very helpful !
I understand that you want to make the activity view to be animated while you load your view controller. The problem is the activity view won't start animating until you return from this selection method... which is about the time when your controller is ready to be pushed.
2 options then:
You could exit from the method asap, calling perfomSelector:onMainThread to do the init steps of the view controller to be pushed
Or even better, push the view controller asap, and do its init process in the viewDidLoad or viewWillAppear methods of this controller (you can add the activity controller in this new view).
If you pick the 1st option, you should call the deselectRowAtIndexPath method after you've pushed the new view controller and call stopAnimating on the indicator view from this deselectRowAtIndexPath method.

Accessing DetailViewController from lower levels of rootviewcontroller in a navigation stack

I've been working on this for the past 11 hours and I think I've figured out what's going on but I can't figure out how to fix it. Basically I'm using the SplitView template for iPad. I have a RootViewController on the left and a DetailViewController on the right.
The main way this differs from the default template is that I'm using the RootViewControler's tableview to present a directory structure. That all works fine until I want to set a label on the DetailViewController from one of the deeper level in rootviewcontroller. I can set the label from the topmost rootviewcontroller but anything lower on the stack doesn't work.
I figure this is happening because every time you move down another level in the directory it pushes another instance of RootViewController onto the navigation stack and these new instances aren't connected to the DetailViewController. What I can't figure out is how to get the new instances to talk to the DetailViewController.
Here's the code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
detailViewController.detailItem = [NSString stringWithFormat:#"Row %d",indexPath.row];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSString *type = [[dataSource objectAtIndex:indexPath.row] objectAtIndex:2];
if ([type isEqualToString:#"tFolder"]) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSString *path = [[dataSource objectAtIndex:indexPath.row] objectAtIndex:0];
UITableViewController *targetViewController = [[RootViewController alloc] initWithPath:path];
[self.navigationController pushViewController:targetViewController animated:YES];
[targetViewController release];
} else if ([type isEqualToString:#"tFile"]) {
NSLog(#"Setting title");
detailViewController.detailItem = [NSString stringWithFormat:#"Row %d",indexPath.row];
}
}
Basically what should happen is if the user taps on a cell that is a folder it will push a new instance of RootViewController onto the navigation stack and display the contents of that directory in it. If the user clicks on a file it should set the detailItem to the name of that file (currently it's just placeholder code) which DetailViewController will then take and change a label on it's view to the file name.
The first detailViewController.detailItem at the top works but only if you're in the topmost RootViewController, the second at the bottom never works because it's only ever called in the lower levels on the stack.
Got it working using
RootViewController* topController = [self.navigationController.viewControllers objectAtIndex:0];
topController.detailViewController.detailItem = [NSString stringWithFormat:#"Row %d",indexPath.row];
Found the solution in this question: Problems accessing rootviewController of navcontroller iphone
I had tried using navigationController.topViewController but it would still return nil. However, using objectAtIndex:0 works.

iphone popviewcontroll problem

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
//Some code to go to the next page
NSString *selectedCountry = [arraycountries objectAtIndex:indexPath.row];
NSString *selectedCountry1 = [arycountries objectAtIndex:indexPath.row];
profilepage *detailViewController = [[profilepage alloc] initWithNibName:#"profilepage" bundle:nil];
detailViewController.selectedCountry = selectedCountry;
detailViewController.selectedCountry1 = selectedCountry1;
// ...
// Pass the selected object to the new view controller.
[self.navigationController popViewControllerAnimated:YES];
[detailViewController release];
This is my code,how can i pass selectedCountry and SelectedCountry1 to profilepage,,,
i try but,i didnt get any values, please help me,thnkzzz
If detailViewController is the next view, you should be using pushViewControllerAnimated:animated: instead of popViewControllerAnimated:. Logically, push goes forward and pop goes backward.
The navigation stack is described in the Navigation Controllers section of the View Controller Programming Guide.
[self.navigationController popViewControllerAnimated:detailViewController
animated:YES];
[detailViewController release];

How to push a view, go back and come back to the view?

I want to build an app for playing local audio files on the iPhone but I'm stuck with some of my codes.
I'm wondering how you can push a view, come back to the uitableviewcontroller and use a button ( like the "NOW PLAYING" button in the media player) to come back to the view without pushing any new string into it..
THANK YOU
What should I change from my codes ?
in the uitableviewcontroller..
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
*)indexPath {
selectedSong = [directoryContent objectAtIndex:indexPath.row];
NSString *storyLin = [[directoryContent objectAtIndex:[indexPath row]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
patch = [NSString stringWithFormat:#"/%#", storyLin];
myDetViewCont = [[mPlayerViewController alloc] initWithNibName:#"mPlayerViewController" bundle:nil];
myDetViewCont.myProgLang = selectedSong; // assigning the correct value to the variable inside DetailViewController
[self.navigationController pushViewController:myDetViewCont animated:YES];
[myDetViewCont release]; // releasing controller from the memory
}
in mPlayerViewController.m
-(IBAction) backtoplayer{
myDetViewCont = [[mPlayerViewController alloc] initWithNibName:#"mPlayerViewController" bundle:nil];
}
If you have pushed a view onto the navigation controller, just pop it to review the view underneath.
That is, the view you push myDetViewCont should just be popped in the backtoplayer call.
- (IBAction)backToPlayer:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
To Add to what Mark said.
Once you've popViewControllerAnimated and the user want to push the same controller again, you just need to keep the mPlayerViewController rather than release it.
Such as:
if (!myDetViewCont)
{ // We only need to create it once.
myDetViewCont = [[mPlayerViewController alloc] initWithNibName:#"mPlayerViewController" bundle:nil];
}
myDetViewCont.myProgLang = selectedSong;
[self.navigationController pushViewController:myDetViewCont animated:YES];
// no longer release here, move the release call to the dealloc

How to pushviewcontroller to a viewcontroller stored in a tabbaritem?

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?