Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
335 views
in Technique[技术] by (71.8m points)

iphone - UINavigationController popToRootViewController, and then immediately push a new view

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The problem and solution to this issue is actually extremely simple.

Calling [self.navigationController popToRootViewControllerAnimated:YES] sets self.navigationController to nil. When you subsequently call [self.navigationController pushViewController:someOtherViewController] you are effectively sending a message to nil, which does nothing.

To workaround, simply set up a local reference to the navigationController and use that instead:

UINavigationController * navigationController = self.navigationController;
[navigationController popToRootViewControllerAnimated:NO];
[navigationController pushViewController:someOtherViewController animated:YES];

As stated by Jason, the popToRootViewController must be performed without animation for this to work correctly.

Thanks go to jpimbert on the Apple forums for pointing this out.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...