Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Littleodie914

macrumors 68000
Original poster
Jun 9, 2004
1,813
8
Rochester, NY
A pretty basic question, but one that I'm having trouble finding a solid answer to. Perhaps I'm not looking in the right places?

I have a separate XIB file containing a UINavigationController. It's in a separate XIB so it can be loaded and displayed from a number of different points in my app.

You can see the layout of the XIB in the screenshot. Now here's the deal... I want that Cancel button to pop the UINavigationController, in any scenario. I would even be alright with providing that Cancel button as an Outlet, and forcing those who load the XIB to set the callback function.

What's the best method to set this up? It must be a common occurrence, and if I were building the UI programmatically, it wouldn't be a problem, but I'm new to designing in IB with separate XIB files. :) I have a sneaking suspicion I need to subclass UINavigationController, provide an outlet for the UIBarButtonItem, and do something like:

Code:
- (void)showSyncWindow:(id)sender {
	NSArray *nibViews =  [[NSBundle mainBundle] loadNibNamed:@"SyncViewController" owner:self options:nil];
	for (id object in nibViews) {
		if ([object isKindOfClass:[MyNavigationController class]]) {
                        MyNavigationController *nav = (MyNavigationController *)object;
                        nav.cancelButton.target = self; // <-- The new lines
                        nav.cancelButton.action = @selector(popWithAnimation:); // <-- The new lines
			[self presentModalViewController:nav animated:YES];
		}
	}
}
 

Attachments

  • Screen shot 2010-10-03 at 8.44.14 PM.png
    Screen shot 2010-10-03 at 8.44.14 PM.png
    249.1 KB · Views: 224
Is this displayed only as a modal view controller, only on a navigation controller stack, or sometimes both? If it's always a modal view controller there is a handy property on UIViewController called parentViewController that you could use to make the modal view controller dismiss itself. If it is both you could first check if the navigation controller is nil, if not, pop the view controller, then check if the parent view controller is nil, and if not dismiss the view controller.
 
If it's always a modal view controller there is a handy property on UIViewController called parentViewController that you could use to make the modal view controller dismiss itself.
parentViewController is not needed to dismiss a modal view. You can simply call:
Code:
[self dismissModalViewControllerAnimated:[I]YES/NO[/I]];
 
parentViewController is not needed to dismiss a modal view. You can simply call:
Code:
[self dismissModalViewControllerAnimated:[I]YES/NO[/I]];
I'm having issues with that method call.

Here's a simplified version of what I'm working with:

UINavigationController (A), currentViewController is UIViewController (B)

in UIViewController (B), I call:

Code:
[self presentModalViewController:(UINavigationController *)nav animated:YES];

nav is a second UINavigationController (C), whose currentViewController is UIViewController (D).

How, in D, can I pop back to B? I've tried:

Code:
[self dismissModalViewControllerAnimated:[I]YES/NO[/I]];
[self.parentViewController dismissModalViewControllerAnimated:[I]YES/NO[/I]];
[self.parentViewController.navigationController dismissModalViewControllerAnimated:[I]YES/NO[/I]];

But none of them produce results. It seems there should be an easy, static way to pop the top-most modal VC? :confused:
 
Code:
[self dismissModalViewControllerAnimated:YES];
works fine to pop back from D to B in a simple test project I threw together (see attached; where D == TwoDetailViewController and B == OneDetailViewController). Perhaps there is something funky going on in your navigation stack(s).
 

Attachments

  • LittleOdie.zip
    746.5 KB · Views: 140
Code:
[self dismissModalViewControllerAnimated:YES];
works fine to pop back from D to B in a simple test project I threw together (see attached; where D == TwoDetailViewController and B == OneDetailViewController). Perhaps there is something funky going on in your navigation stack(s).
Thank you very much for taking the time to put that project together, it's a great reference. I've taken a closer look at my setup, and the issue appears to be related to the fact that the second UINavigationController I'm showing as the modal view is loaded from a .XIB.

Take a look at this snippet:

Code:
- (void)showSyncWindow:(id)sender {
	NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"SyncViewController" owner:nil options:nil];
	for (NSObject *object in nibObjects) {
		// Part One
		if ([object isKindOfClass:[SyncNavigationController class]]) {
			[self presentModalViewController:(SyncNavigationController *)object animated:YES];
		}
		
		// Part Two
		if ([object isKindOfClass:[SyncViewController class]]) {
			SyncViewController *vc = (SyncViewController *)object;
			
			SyncNavigationController *con = [[SyncNavigationController alloc] initWithRootViewController:vc];
			vc.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStylePlain target:vc action:@selector(dismissModalViewControllerAnimated:)];
			[self presentModalViewController:con animated:YES];
		}
	}
}

If Part One is used, things don't work. The button doesn't appear to do anything. (Don't worry, the button is properly connected to the exact same method as Part Two.)

If Part Two is used instead, things work perfectly.

So it seems if I present the existing navigation controller, something isn't hooked up properly. But if I create a brand new navigation controller, which it seems like what *should be* happening when the XIB is loaded, then things work as expected.
 
Hm, I scrapped the idea of keeping the UINavigationController in the XIB. The XIB now just contains my instance of the UIViewController, and whenever the modal view needs to be presented, I instantiate a new UINavigationController on the fly, injecting the UIViewController from the XIB. (Set as an IBOutlet.)

Not sure what the original problem was, but this is easier and less headache-causing. :)
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.