I do not know the answer to the first part of your question, but once you learn the answer to the second part, I am sure that you would go with a different solution anyway.
viewDidLoad
method is called every time. So, does that mean I created new object instance each time viewDidLoad
method was executed?
Absolutely. "Modal" segue causes the new view to obscure the old one completely until the new view is closed. If you go back and forth many times, your code will accumulate a whole "stack" of views underneath the current one.
I also notice that viewDidUnload
method is never called. So, if answer to previous question is affirmative (each viewDidLoad
execution creates new object instance), does that mean that my UIViewController
object instances are never being unloaded and deleted?
This is correct, all the view controllers that you create are still there, ready for you to close the views on top of it.
Or ARC is doing garbage collection behind the scenes?
ARC is not a garbage collector, it is a reference counting mechanism with a little automation from the compiler. The objects are still there.
You should change your code to call
[self dismissModalViewControllerAnimated:YES];
in the second controller, rather than using a modal segue that brings you back to the first one.
Unwind segues use runtime searching by first asking the parent view controller to walk up the chain of view controllers presented via segue until it finds the correct unwind method. But there is no chain here since the popover was created programmatically rather than with a popover segue.
No callbacks are occurring since there is no segue link back to the parent view controller. Unwind segues are an abstracted form of delegation, so this would be similar to forgetting to set the delegate and not receiving any callbacks.
The solution is to create the popover with a segue in Interface Builder rather than create it programmatically with the configChartTapped:
method.
Steps:
First, control-drag from the bar button item in the presenting view controller to the presented view controller and select the popover segue:
In the presenting view controller, implement prepareForSegue:
to grab a reference to the popover controller:
- (void)prepareForSegue:(UIStoryboardPopoverSegue *)segue
sender:(id)sender {
self.popover = segue.popoverController;
}
Then implement shouldPerformSegueWithIdentifier:
to restore
the show/hide behavior similar to configChartTapped:
:
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
if (self.popover.isPopoverVisible) {
[self.popover dismissPopoverAnimated:YES];
return NO;
} else {
return YES;
}
}
Finally, in Interface Builder, set the correct popover content size for the presented view controller:
This will allow you to unwind to cancelConfig:
when tapping the cancel button from the popover, and also show/hide the popover when tapping the button that presents it.
Best Answer
In a Nutshell
An unwind segue (sometimes called exit segue) can be used to navigate back through push, modal or popover segues (as if you popped the navigation item from the navigation bar, closed the popover or dismissed the modally presented view controller). On top of that you can actually unwind through not only one but a series of push/modal/popover segues, e.g. "go back" multiple steps in your navigation hierarchy with a single unwind action.
When you perform an unwind segue, you need to specify an action, which is an action method of the view controller you want to unwind to.
Objective-C:
Swift:
The name of this action method is used when you create the unwind segue in the storyboard. Furthermore, this method is called just before the unwind segue is performed. You can get the source view controller from the passed
UIStoryboardSegue
parameter to interact with the view controller that initiated the segue (e.g. to get the property values of a modal view controller). In this respect, the method has a similar function as theprepareForSegue:
method ofUIViewController
.iOS 8 update: Unwind segues also work with iOS 8's adaptive segues, such as Show and Show Detail.
An Example
Let us have a storyboard with a navigation controller and three child view controllers:
From Green View Controller you can unwind (navigate back) to Red View Controller. From Blue you can unwind to Green or to Red via Green. To enable unwinding you must add the special action methods to Red and Green, e.g. here is the action method in Red:
Objective-C:
Swift:
After the action method has been added, you can define the unwind segue in the storyboard by control-dragging to the Exit icon. Here we want to unwind to Red from Green when the button is pressed:
You must select the action which is defined in the view controller you want to unwind to:
You can also unwind to Red from Blue (which is "two steps away" in the navigation stack). The key is selecting the correct unwind action.
Before the the unwind segue is performed, the action method is called. In the example I defined an unwind segue to Red from both Green and Blue. We can access the source of the unwind in the action method via the UIStoryboardSegue parameter:
Objective-C:
Swift:
Unwinding also works through a combination of push/modal segues. E.g. if I added another Yellow view controller with a modal segue, we could unwind from Yellow all the way back to Red in a single step:
Unwinding from Code
When you define an unwind segue by control-dragging something to the Exit symbol of a view controller, a new segue appears in the Document Outline:
Selecting the segue and going to the Attributes Inspector reveals the "Identifier" property. Use this to give a unique identifier to your segue:
After this, the unwind segue can be performed from code just like any other segue:
Objective-C:
Swift: