Reputation: 331
I am creating a modal view (OnlinePeerBrowser) from within a navigation subview (ConnectionScreen). I need to reference methods from the parent view of the Modal view. For some reason, the modal view believes it's parent is the rootView and not the view I created the modal from.
What am I doing wrong?
My code to create the modal view
@implementation ConnectionScreen {
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = @"ConnectionScreen";
}
return self;
}
...
- (void)peerPickerController:(GKPeerPickerController *)picker didSelectConnectionType:(GKPeerPickerConnectionType)type {
if (type == GKPeerPickerConnectionTypeOnline) {
OnlinePeerBrowser *controller = [[OnlinePeerBrowser alloc]
initWithNibName:@"OnlinePeerBrowser" bundle:nil];
[self presentModalViewController:controller animated:YES];
NSLog(@"my current view title: %@", [self title]);
NSLog(@"parent of the controller title: %@", [controller.parentViewController title]);
The output is:
my current view title: ConnectionScreen
parent of the controller title: Home
The modal view is being created and presented as a ModalViewController from within a ConnectionScreen instance. Why is it using the root window as the parent?
------- More on this ----------- I filed a bug with Apple thinking I was smart ;). They actually identified an issue with my code with pushing the nav controller (Scroll to bottom to see). I don't see what am I doing wrong. They also made sure this type of thing doesn't happen in 5.0 with gracefully exiting addressing an API change as Vinnie states below.
If anyone can see what I am doing wrong with the view pushing below, I would appreciate it. ------- More on this -----------
just received a response from Apple after filing a bug report on the ModalViewController for iOS development. I am trying to deciper their response. (Note the support response says confidential. Since you are all registered Apple developers, I thought it would be ok to share.)
From the response below, I can't tell if they are they saying that my approach to creating the navigation controller and pushing the root view is wrong, or if they admitting to the bug and stating that they reconciled this in iOS 5.
Here is the code I submitted to repeat the 'bug'.
The response to the bug I filed:
Steps to Reproduce: Create a navigation controller Push a view controller with the title 'Home' Create a button on the 'Home' view controller that pushes another view controller 'NewView' On 'NewView' create a button that pulls up a modal view In that modal view call self.parentViewController.title
Expected vrs Actual Results: The parent title of the modal view should be NewView; however, it shows that the parent view of the modal view is Home.
Notes: My workaround is to set a property on the modal view, myParent, prior to making the modal view visible.
Their response
Engineering has determined that this issue behaves as intended based on the following information:
This test application will exit with a UIViewControllerHierarchyInconsistency in 5.0. The applicationDidFinishLaunching method is highly suspect (and the cause of the 5.0) exception. The window's root view controller is being pushed as the child of a view controller whose view is then added to the window.
This is likely causing of all sorts of inconsistencies, hence why we now raise the issue on 5.0. Note that in 5.0, parentViewController no longer returns the modal presenter. We added the method presentingViewController to cover this case. parentViewController is now reserved to indicate a containment relationship between view controllers.
The code they claim is suspect:
{
// Override point for customization after application launch.
self.navigationController = [[UINavigationController alloc] init];
self.window.rootViewController = self.viewController;
[self.navigationController pushViewController:self.window.rootViewController animated:NO];
// Add the navigation controller's view to the window and display.
[self.window addSubview:self.navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
Upvotes: 0
Views: 649
Reputation: 1730
If testing this in iOS 5, you're going to get the incorrect value for this property. As of iOS 5, parentViewController is no longer set when presentModalViewController is called. Instead, you will have to use the presentingViewController property. If however, you are supporting other versions of iOS, you will have to get slightly fancy. Either do some checking like this:
if([self respondsToSelector:@selector(presentingViewController)])
;//... do stuff to the presentingViewController
else
;//... do stuff to the parentViewController
You could also set your own delegate or create some customParentViewController property to be sure. I personally went this route.
Some people just want to call [self.parentViewController dismissModalViewController]. In that case, use [self dismissModalViewController] because it will just climb up the stack for you and dismiss itself.
And yes, any code written in iOS 4 and below has now been broken on iOS 5 devices so check your other apps in the app store.
Upvotes: 3
Reputation: 13267
This is all within the same function, so ALL of the code is run at the same time. You said that the app is functioning normally UI wise, so the NSLogs should really be placed in the viewDidLoad function of OnlinePeerBrowser. Then it should work properly.
Upvotes: 1