I have a modal view which is launched from the current view controller, as
[self presentModalViewCOntroller:modalViewController animated:TRUE];
The modal view controller dismisses itself when someone hits a button.
[self dismissModalViewControllerAnimated:TRUE];
A couple of screens later, I attempt to swap the root view within the window. I do this all the time with no trouble. But in a certain case, when switching the one view within the window, the picker delegate method is being called on the modal view controller even thought it was dismissed a while ago.
This is very strange because the modal view controller is usually deallocated when dismissModalViewController is called.
Why is a view from the modal view controller being invoked?
It appears that someone, probably the window still has a reference. Are you supposed to do something else in addition to dismissModalViewController?
Thanks
DismissModalViewController should be enough. It does seem like you have a problem with some reference hanging around that you don't intend. Without seeing more code, I can't point to anything specific.
Related
I was trying to create a UIAlertController on ViewWillAppear, it was giving me the below warning.
"Warning: Attempt to present <UIAlertController: 0x7f8798c15df0> on <ViewController: 0x7f8798f81450> whose view is not in the window hierarchy!".
My Understanding it is ready to show the view to the user in ViewWillAppear, but fairly expensive.
However when i moved the same UIAlertController code to ViewDidAppear it was showing the Alert Msg.
Can you please clarify whey the alert msg is not getting show in ViewWillAppear.
UIAlertController is unlike the typical UIAlertView, which inherited from UIView. Adding a UIView in viewDidLoad, appear, etc. is no problem because you are adding it that view controller's view hierarchy.
Now, with UIAlertController, it's a first class view controller. This means that you should present it the same way you would other view controllers - all the same rules apply.
In viewWillAppear, the view controller isn't done being added to the window's hierarchy, so it's a poor choice to present the alert controller. As you found, viewDidAppear is the way to go here.
viewWillAppear: is not a good location to present another view controller since the current one being presented is not yet in the window hierarchy and is also in a transition animation. You should either use viewDidAppear: or add a slight delay before displaying the alert controller.
Most answers on here cover the topic pretty well, I just wanted to add additional details. It typically is not problematic to add child view controllers in viewWillAppear: or even viewDidLoad:. In fact if you use a container view controller in IB then it will be integrated before either of these are called.
The problem is more so to do specifically with the alert controller. Alert controllers function on a different window hierarchy than your typical UI (think Z axis) and manipulate the UI in a more intensive way than a standard container (since it is not a container).
In order for the alert to properly present it must happen after the current view is displayed (there could be a number of reasons here). This is why presenting it in viewDidAppear: worked (since the current vc's view will be fully live).
The same error may occur if parameters of UIAlertController are nil, such as title, message
I have an interesting problem that has me stumped. I have a view that is displayed on top of another view (using addView). The second view does not fill the entire screen on the iPhone. Both views are managed by view controllers. The second view controller then presents a modal view controller that fills the screen (specifically MFMessageComposeViewController).
All of this works great the first time. However, when I dismiss the modal view controller the second time, the dealloc method on the presenting view controller (the one that presents the modal) gets called by __delayedPerformDealloc.
The containing view controller has retained the inner view controller, so I can't figure out what list the inner view controller got on that caused it to be dealloc'd.
Has anyone else seen this?
Tools: Xcode 4.5.2, iOS 6, iPhone 5.
This turned out to be a bonehead move by me. The controller in question was being passed as a delegate and was assigned to a member variable in the init method but was released in the dealloc method. D'oh!
I've seen this question a couple of times but never really answered. I'm wondering if there is an acceptable/clean way to dismiss all launched view controllers and return to the initial view controller when using storyboards (say from an action within a spawned view controller).
I know how to use delegates, but, I'd prefer to not have my initial view controller implement delegates for every possible spawned view controller. Instead, I'd just like a home button that cleans everything up and returns to the initial view controller from anywhere in the app.
Thoughts?
EDIT: Just for clarity, assume I am NOT using UINavigation Controllers.
EDIT2: Is it possible to just access the methods of the "initial view controller" from anywhere in the app like you might do with the appDelegate?
This should do it at any point. Just stick it in an IBAction and hook it up to a button :)
[self.navigationController popToRootViewController];
I ended up using a singleton. Seems to work quite well.
On the initial load of the initial view controller, I set the view controller as the singleton's property. I can then execute the following code in any action method on any view controller in the app to dismiss all view controllers and return to the initial view controller.
initialViewControllerManager *ivcManager = [initialViewControllerManager sharedInstance];
LPViewController *ivc = ivcManager.initalViewController;
[ivc dismissModalViewControllerAnimated:YES];
May not be the "right" answer, but, seems to work. And, given the complexity of my scenes, relying exclusively on UINavigationControllers would be very complicated.
I got two viewControllers using a navigation bar. The first viewController displays some data I change on the second viewController.
So if I load the second viewController, a back button appears in the NavBar and I can change my values (and they are stored, I used the debugger). My problem is, after hitting the backButton to come to my firstView Controller, it does not call it's viewDidLoad method. It's clear, that there are no updated values at all, when this function is not called.
At the first start, the viewDidLoad method is called and does what I want it to do. After going back and forth between the viewControllers the method is not called again.
Any solutions?
Thanks!
EDIT:
SOLVED
I did not want to delete my question, maybe someone needs this too:
This method is called every time the view appears, it is probably not defined by default:
-(void)viewDidAppear:(BOOL)animated
{
NSLog(#"View appeared.");
}
But the update code (like [[self view] setNeedsDisplay];) in viewWillAppear.
To make it clear: viewDidLoad is called when your view is loaded. This happens at the first time the view is going to be displayed. When you then navigate to the next view the first view can (depending on your code) still be loaded. Therefore when you navigate back to that view viewDidLoad won't be called because the view is still there.
But every time the view is going to be shown (for example when you navigate back to this view) the method viewWillAppear and viewDidAppear will be called.
Hope that helps.
ViewDidLoad method will get called when there is view controller allocation-initialization happens. In the case of moving back in navigation controller, it is not creating any new view controllers, it is reusing previous references from navigation stack.
Hence viewDidLoad will not get called. As your view controller is already in memory stack. So it will just make the view to reappear on windows and it will call viewWillAppear respectively.
I need to save my data by calling a method I already have when a viewController is popped using the back button created by the UINavigationController.
Is there a way to get a delegate callback or a notification I didn't see anything in the documentation?
In your viewWillDisappear method, you can check the property:
[self isMovingFromParentViewController]
to find out if the view is disappearing as a result of being popped off the stack or not.
You will be notified that the view will be disappearing, with the view controller method viewWillDisappear:, however, this will be called each time the view is moved offscreen, whether that means the controller is popped or a new controller is pushed, or whatever else may cause your view to disappear.
Perhaps a better design would be to save your data in your controllers dealloc method. Normally, a navigation controller is the owner of a view pushed into it's stack, so popping it usually causes it to deallocate. This isn't always the case though and depends on how you've written your app.