iOS 5 -- presentModalViewController nils parentViewController in "self"? - iphone

I'm still trying to figure out some iOS 5 vs iOS 4 problems in this incredibly (and unnecessarily) complicated app.
I've traced one problem down to the fact that a controller (which happens to be the navigation controller of the calling class) has a parentViewController attached prior to being "sent" a presentModalViewController request, but on the other side of that (in viewWillAppear of the "presented" controller -- haven't even returned from the call) the navigation controller (I've verified that it's the same address) suddenly has a nil parentViewController.
I'm reasonably certain that this behavior did not occur in iOS 4 (I've been ping-ponging back and forth between the two versions to verify behaviors).
The code is far too complicated to include here, but the call is:
[self.navigationController presentModalViewController:messageViewController animated:[self isAnimated]];
There are assertions prior to the call that the parentViewController of the nav ctlr is non-nil, and likewise in viewWillAppear. The assertion only fails in viewWillAppear.

It was in the manual: Change in iOS5

More good information about this iOS5 change:
http://omegadelta.net/2011/11/04/oh-my-god-they-killed-parentviewcontroller/

Related

"viewWillAppear" not call in xcode 4.5 with iPhone 4.3 simulator

"viewWillAppear" not call in xcode 4.5 with iphone 4.3 simulator, but if it runs in iPhone 5.0 or iPhone 6.0 simulator, this method will be called.
why? and what can i do if i want to do something when the view of an controller will appear in ios 4.3?
I think it may be related to the "View Controller Abusing". Check if your container view controller is used correctly. You can refer to this post for detail.
Based on your comments, the problem appears to be the lack of container view controllers in iOS 4. As of 5+ you're explicitly meant to be able to add the view of any controller into the view of any other* and that will generate the appropriate view[Will/Did]Appear, along with all the other newer messages — viewDidLayoutSubviews, etc.
In 4 you weren't explicitly allowed to build container view controllers and there's no deliberate, specific backwards link that connects a view back to its controller.
As a result, when you add the navigation controller to your view it doesn't get viewDidAppear. Because it doesn't know that its view has appeared, it doesn't tell any of the controllers it contains that their views have appeared.
Probably the best you're going to be able to do is to hack around that by (i) checking if you're operating under iOS 4; and (ii) if so, posting artificial viewWillAppear/viewDidAppear/viewWillDisappear/viewDidDisappear to your contained controllers.
Based on personal experience, iOS 4 (at least in 4.3) does actually implement addChildViewController: but not to do what the later, documented version does. So despite it not being an entirely accurate functionality check I tend to use if([self respondsToSelector:#selector(presentingViewController)]) to determine whether I need to propagate these messages manually.
[*] and you should also call addChildViewController: to make sure all messages move correctly in all directions

Xcode application running on Iphone but crashing on Ipad

I made a universal application that contains NIB files for both ipad and iphone UI's. In my view controllers initWithNibName method I call UIUserInterfaceIdiomPad == UI_USER_INTERFACE_IDIOM() to detect whether the controller is running on iphone or ipad.
I then launch their respective nib files. When I run the app on iphone, it works fine, but when I run it on ipad it eventually crashes with a EXC_BAD_ACCESS error. This error occurs when I use a view controller to launch another view controller, which then launches another one in the navigation stack. This error occurs as soon as I click the view that belongs to the third controller of the stack.
I cannot distinguish a difference between the NIB files that would cause a crash. I have been working tirelessly to figure out why this is happening but I cannot fix this error. Does anyone have any insight into what might be going on?
Any advice on how to approach fixing this problem would be very appreciated.
The first thing you should do is enable the "All Exceptions" break point. This will often accurately tell you the line of code where the EXC_BAD_ACCESS is happening.
Next, I would turn on zombies and see where the over-release is happening. To do so, in Xcode, while holding the option key, click Product | Run.... In the ensuing window, add NSZombieEnabled to the environment variables list.
Then run. Do the normal things you do to cause the crash and see where the debugger lands. With any luck, it will stop where the problem is actually occurring.
When you get a EXC_BAD_ACCESS it means you're trying to access/release something that's already been released. If you're in a non-ARC situation, it normally means you've inadvertently released something when you didn't mean to, so just check for alloc/init and release balance. If, however, you're in an ARC situation, I would bet it has to do with not niling a delegate when a view controller gets released.
For example, if you have a MKMapView and have set its delegate to your view controller, you should nil its delegate when your view gets unloaded or dealloc'd. Otherwise, messages will continue to get set to it. Or, another possibility is that you've added your view controller as an NSNotificationCenter observer and didn't remove it as an observer when the view controller was unloaded or dealloc'd.
Another possibility is that you're re-using view controllers between the two versions of your universal app. If you are accessing anything by an identifier that doesn't exist in the nib for the iPad, that would cause a crash--though if you're using nibs as opposed to storyboards, that may not be an issue.
That's about all I can think of for now. Try to zero in on where it's happening and post code here if you still can't figure it out.
Best regards.

UISplitViewController not calling view delegate method in ios 5

I noticed this symptom in iOS 5 - Create an UISplitViewController with ViewController 1 on the left and ViewController 2 on the right. Open the popovercontroller in portrait, then close the popovercontroller. Viewcontroller 1's viewWillDisappear/viewDidDisappear methods does not get call. But in iOS 4.3 viewWillDisappear/viewDidDisappear methods does get call.
Anyone aware of a explanation for this change in behavior?
Apparently automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers method of the UISplitViewController is set to return NO instead of YES. So subclassing UISplitViewController and overriding automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers to return YES solved the problem.
Cheers!
I tried this with the unmodified split view controller template (master-detail app, iPad only, no storyboard) and I can't confirm your observation. The appear/disappear callbacks are called, for both children of the split view controller.
So there must be something else happening in your app; our initial conditions are clearly not the same, somehow... Or we might not be talking about exactly the same callbacks at the same moments. There is a clear note in the documentation ("Message Forwarding to Its Child View Controllers") about how a split view controller forwards these callback messages.

iOS 3.1.2 [UIViewController dismissModalViewControllerAnimated:] creates infinite recursion

I have some code that works fine on my iPod Touch running some 4.0-series iOS as well as the simulator that comes with the iOS SDK 4.1. But when I call [UIViewController dismissModalViewController:] on an iPhone 2 running iOS 3.1.2 it get an infinite recursion, eventually crashing.
I have a view controller that opens a table view where the user selects a document to open. Upon selecting a document my table view controller's delegate calls the parent view controllers dismissModalViewController method. I think it is because I'm closing the view controller whose code is running that causes this.
dismissModalViewController is documented to be available in iOS 2.0 and later.
How can I close the UIViewController that's open from its own code?
I figured my problem might be heap corruption from some previous code. A way to debug that is to comment off snippets of previous code to see whether the bug would go away or come back. Almost immediately I found that I was calling dismissModalViewControllerAnimated: on the current view controller's parent controller. Why that works in iOS 4.x I have no idea. The problem I face is that I have two modal dialogs that I need to close simultaneously, which I cannot get working, but that is a different question.

Different values (nil and non-nil) for self.navigationController depending on stack location

I have a UIViewController subclass that accesses self.navigationController in viewDidLoad:. Depending on where it is in the view stack, I will either get the navigationController or I will get nil.
If my stack is "RootViewController -> MyViewController", I get a valid pointer.
If my stack is "RootViewController -> AnotherViewController -> MyViewController", I get nil.
In both cases, MyViewController is being pushed onto the stack with:
[self.navigationController pushViewController:self.myViewController
animated:YES];
This has me stuck, because I need to be able to push another ViewController on the stack above MyViewController, which works fine in the first case but obviously fails on the second.
from everything I can see the UIViewController's self.navigationController is designed to always return the appropriate UINavigationController as long as the UIViewController exists within a UINavigationController's stack. This is probably one of those cases that I seem to run into myself more often than I'd like where a simple coding error is masquerading as something much more complex. In these cases I usually have good luck setting up an entirely new Xcode project with the minimal code needed to reproduce the issue and more times than not in that process I find a fix for something I overlooked that can then be easily applied in the main project. I'm sorry I can't offer more specifics but what you are describing seems to go against the design of the Cocoa Touch framework and if you can still reproduce it in a minimal Xcode project written in strict accordance with the documentation it may be a good idea to file a bug report with Apple. Hopefully though you will just find something simple you overlooked and be kicking yourself in a few minutes =)
What I usually do is subclass UIViewController and add a method to set the navigationController. There's no reason not to have this as read/write, especially considering how often Apple's classes will decide not to set the navigationController (or the parentController, for that matter) even if they are in the same stack.