I have a older iOS app that I am working on a update for. Compiling with 8.2 and 8.3 SDK I get unwanted pops to the root view controller, running on 8.3 or 7.1 iOS. Depending on the specific view configuration when I add the 2nd view to the stack I will get a instant, after viewDidAppear, pop to the rootViewController from the 2nd view or 3rd view on the stack. I have breakpointed all my popTo statements and non of them are causing it. I am getting no indication of the cause. Are there any debug tools that can help me find this?
You can subclass the navigation controller and override the popToRootViewController method with an implementation that just calls super. Put a breakpoint in there and you should be able to pinpoint the cause. (Make sure you replace the default navigation controller with the subclass).
If popToRootViewController still does not get called, the other view controllers might be getting deallocated or dismissed for some reason.
Related
I'm experiencing something really weird :
Create an extremely basic single view project, and add a second view controller to the storyboard, along with a modal segue from the first to the second. Initiate the segue from the view controller and trigger it programmatically with performSegueWithIdentifier:.
In the viewDidLoad of the modally presented view controller, add this log :
NSLog(#"%#", self.presentingViewController);
Now run the app on iOS 7, you should get a log like this one :
<ViewController: 0x7fa8e9530080>
Which is just the reference of the initial view controller of the app, which presented the modal view controller.
Now run the exact same thing on iOS 8, and you will get :
(null)
What's going on here ? Is it a known issue ? Of course I'd expect the exact same behavior on both systems.
Thanks ... Formalizsed as answer.
viewDidLoad should really be used for initialization, At this stage, there is not guarantee that the receiver's controllers view hierarchy has been placed in the navigation tree. If that is your intent, you should override viewWillAppear or viewDidAppear. Whilst it works in earlier versions, the docs clearly state that it should be used for additional initialization. It certainly sounds as though in iOS 8, the receiver's initialization is being performed earlier
Wondering if anyone else has encountered this issue recently...
For one of my view controllers , only on iOS 8, after calling presentViewController:animated:completion:, the presented view controller has self.presentingController as nil. It is fine on iOS7, and also does not happen on another view controller.
The documentation says that it should be set, as long as the presented view controller was presented modally. Given it works in iOS 7, could this be an iOS 8 bug?
I've been able to get around it using a view container containment approach, but it would be good if someone has seen this before and knows the root cause that triggered this behaviour.
thanks
Had a similar issue with iOS 8, where presentingController is nil when checking the value in viewDidLoad.
When viewDidLoad is called, there is no guarantee that the view controller hierarchy is loaded in the navigation tree. Moving the logic to a later stage (for example: viewWillAppear) should resolve that issue as presentingController should be loaded by then.
I've been dealing with this (somewhat) random bug for a while and can't figure out the problem. The context: I'm creating an UISplitView iPad app that have a UINavigationController inside the Master view:
Main menu in red, submenu in green and main content in purple.
This UINavigationController does not fill the entire Master view because I need some space to have a vertical menu. When a user select a button on the vertical side menu, it sets something new to the UINavigationController to show a UITableView with options. What I'm doing on every menu selection is:
[self.subMenu setViewControllers:#[subMenuViewController] animated:YES];
What happens is that I don't need to keep the menu history, so what I do is I set a new root view controller to the subMenu every time.
The issue is when I start messing with the device orientation. It doesn't have a clear pattern, but sometimes, when rotating, my app crashes. Now when I run it with Instruments, this is what I get:
167 Zombie -1 00:32.101.527 UIKit -[UITableView _spacingForExtraSeparators]
And the interesting thing is that the bad access happens on the previous root view controller of the subMenu. So if I tap "Events" and then after that I tap "Podcasts", the bad access happens on trying to access "EventsViewController".
So I'm guessing something is not right on my way of replacing the root view controller of the subMenu UINavigationController, but I'm not sure what it is. Maybe I need to make sure the current root view controller is released before setting a new one?
Any help is much appreciated. :)
It's not uncommon to crash in system library code due to something you didn't set up quite right. This might be that your UIWindow, UIApplicationMain or its content view or your view controller instance was not retained or got released somehow.
That shouldrotate method won't help if your controller isn't still around.
This is to identify which object got released.
For particularly thorny problems, you could add release, retain, and dealloc methods (that log and call super) to a suspect class of yours and see what's releasing it. Log the -retaincount to keep track (I only use this for diagnostic purposes,)
Or you can try this, set a breakpoint on -[UIDevice setOrientation:] and step through your code in the debugger.
To make debugging easier, you can type call (void)instrumentObjcMessageSends(YES) right in the debugger console to begin logging objc_msgSends to /tmp/, then continue execution and it will trace all the messages that are sent right up until the crash.
So first, you should implement the methods willRotateToInterfaceOrientation, willAnimateToInterfaceOrientation and didRotateToInterfaceOrientation (check the actual signature of these methods) in your view controllers that contain a UITableView.
In each of these methods check the your table view dataSource and delegate. I think this crash is caused by a release of the delegate or table view's datasource.
Also you should check what table view delgate/datasource methods are called during rotation.
And the last thing, make sure you discard the old instances of subMenuViewController and they are properly removed from the parent view controller.
I need to open a popover from a subview inside a ModalView. These subviews are added on ModalView at viewDidLoad using [self.storyboard instatiateViewControllerWithIdentifier:identifier]
When I click to open a popover the application exit without any information about the crash.
the sample project with this error can be downloaded here (https://www.dropbox.com/s/mjpaqk6xwt86dbd/PopoverTest.zip)
I´m using xCode 4.3.1 and iOS SDK 5.0 and storybord.
thanks
André
In viewDidLoad, you're instantiating a bunch of view controllers with instantiateViewControllerWithIdentifier:, but those aren't retained or referenced anywhere after that. I'm pretty sure ARC is releasing them for you at the end of viewDidLoad, which is causing the crash. If it didn't do this, it would be a leak.
One solution would be to store those view controllers in an array, and release it on viewDidUnload.
I have a Master/Detail view which opens a popover view via storyboard segue. There is an add button on the navigation bar of the Master view controller which works fine.
I added an editing mode where the same popover is invoked by selecting a table cell in edit mode. It fails from the [self performSegueWithIdentifier:#"addQuery" sender:self]; statement. The viewDidLoad in the popover is invoked, but after that the exception is thrown.
I am not invoking presentPopoverFromBarButtonItem - it seems to be coming from the performSegueWithIdentifier.
There is no question that the Master View Controller has a window - a table cell for that view was clicked to start the whole process that is failing.
The popover is the beginning of a navigation controller sequence, which may be part of the problem. Everything is working fine when it really is invoked by the button, just trying to programmatically invoke it is failing.
I have tried changing the "sender" for the performSegueWithIdentifier to no avail.
I suspect the problem has to do with the segue not being invoked by a button, and I do not know how to fake that out.
Any ideas?
There appear to be some bugs in how ipad popover segue's work - see Wayne Hartman's blog post
A simple test revealed that viewWillAppear is being called after viewDidLoad.
I think I understand the problem... havent' worked out the solution yet.
The order in which the methods were called are...
[initiate segue]
viewDidLoad
prepareForSegue
viewWillAppear
I moved my initialization code to the viewWillAppear method - and it worked.
In general, I feel it may be a good idea to initialize within viewWillAppear instead of viewDidLoad anyway.
I have a similar issue:
I am using UIDocumentInteractionController to open a kaynote document in Kaynote app. I was using same code:
[docController presentOpenInMenuFromBarButtonItem:_actionBarButtonItem animated:YES];
Code above was opening popover from actiobBarButtonItem with options what app I would like to use to open my file. If I same thing from DetailViewController I get same error message as author of this thread: "Popovers cannot be presented from a view which does not have a window"
And I was able to find a quick solution for my issue . I am not sure if it will be relevant to yours. Instead of using "presentOpenInMenuFromBarButtonItem" I used "presentOpenInMenuFromRect" and thats it. You just need to define right place for popover to apear