views:

1066

answers:

2

Hi there,

I have a tabBarController with two tabs, first of which contains an instance of NavigatorController. The navigatorController is initiated with a custom viewController "peersViewController" that list all the network peers on a tableView. Upon selecting a peer, an instance of "FilesListViewController" (which list files in the c:\ directory) is pushed into the navigationController stack.

In this filesListViewController I have a button to let it navigate to say documents directory. To do this I'd wired the interface to call a gotoDirectory:(NSString*)path method in the rootViewController:

- (void)gotoDirectory:(NSString*)path {
     [[self navigationController] popToRootViewControllerAnimated:YES];
     NSArray *files = [self getFilesFromPeerAtPath:path];
     FilesListViewController *filesVC = [[FilesListViewController alloc] initWithFiles:files];
     [[self navigationController] pushViewController:filesVC animated:YES];
     [filesVC release];
}

However, when I press that button, the navigationController did pop my view to the root view controller, but then the FilesListViewController that I instantiated did not appear. From the log, I know that the custom initWithFiles method was indeed called and network stuffs did happen to get the file names.

Something else is screwy about this. I tried clicking on the second tab and then click back to the first tab, and huala! the file names I needed are there. It looks like the data and the filesListViewController was indeed pushed into the navigatorController stack, but the display was not refreshed but stuck at the screen of rootViewController (peersViewController).

Am I doing anything wrong?

--Ben.

-- Edited like 15 minutes after posting the question. I'd found a workaround, but it bothers me that pop and then push doesn't work.

- (void)gotoDirectory:(NSString*)path {
     PeersListViewController *rootViewController = (PeersListViewController*)[[[self navigationController] viewControllers] objectAtIndex:0];
     [[self navigationController] setViewControllers:[NSArray arrayWithObject:rootViewController]];
     FilesListViewController *filesVC = [[FilesListViewController alloc] initWithFiles:files];
     [[self navigationController] pushViewController:filesVC animated:YES];
     [filesVC release];
}

It doesn't seem like the navigationController should be circumvented this way, and I'd probably have to release all the viewControllers that were in the original stack. This does however work on the iphone 3.0 simulator.

If I'm using this code though, how should the memory release be handled? should I get the original NSArray of viewcontrollers and release everything?

+2  A: 

Hi,

I got a very similar problem (but without using tab).

I got three viewController : main(root), form and result. when the UINavigationController stack is

"main -> result"

on a btnClick I do a popToRootViewControllerAnimated then a push of the formViewCtrl. in order to have

"main -> form"

the navbar title and back button label are correct and the formViewCtrl's event are called. BUT, I still see the main view.

Here is my "solution"

After doing some test, I found out that without the animation to go to the rootViwCtrl this work fine. So I only use the animation to push viewCtrl.

iPhone 3.0, problem found on device & simulator.

If i got something new, i will update/comment my post.

Loda
Yeah, you need to pop without animation (so that it happens right away) and then push with animation. If you try to do two animation changes right together (which take time to complete) the view will get in a bad state.
Jason
Exactly as described, this doesn't work for me.I think it's a timing issue on stack changes (Apple's animation code is very fragile, it's implemented poorly) - this technique may or may not work depending upon how much else is on screen, it seems.
Adam
+1  A: 

Hi, I found a workaround but I cannot explain why it is working: 1. First push the needed controller. 2. Then pop to the one you want to.

This is totally illogical, but it works for my case. Just to make things clear, I'm using it in the following scenario: First Screen -> Goes to Loading Screen -> Second Screen When I'm on the Second Screen, I don't want to have the Loading Screen in the stack and when click back I should go to the First Screen.

Regards, Vesko Kolev

Vesko Kolev
This really shouldn't work. But it does.In 3.0, I've found that the classic approach (direct manipulating the viewControllers array) doesn't always work as expected, so I'm trying this workaround instead.
Adam