I'm creating custom transitions in my app and running into two problems. If I set the view controller to handle both UIViewControllerAnimatedTransitioning
and UIViewControllerTransitioningDelegate
I run into the problem of my view controller never being deallocated. Specifically, this creates the retain:
self.transitioningDelegate = self;
If I don't do that, and put UIViewControllerAnimatedTransitioning
and UIViewControllerTransitioningDelegate
in a separate NSObject
called TransitionController and set it like this:
self.transitioningDelegate = [[TransitionController alloc] init];
the UIViewController
is deallocated , but I get memory leaks on the TransitionController object. Does anyone now what I'm doing wrong?
I ran into the same issue and was able to solve it.
The custom transition API is not that well documented and required a lot of trial and error for me to get everything right.
Let me walk you through how I was able to make it work nicely without any memory issues:
VCA = The view controller that wants to present VCB modally
VCB = The modally presented view controller (presented by VCA)
TC = The custom transition controller object that performs the custom animation.
NSObject subclass that conforms to " UIViewControllerAnimatedTransitioning ".
Will be instantiated within TD.
TD = The custom transition delegate object that provides the transition controller to the system. NSObject subclass that conforms to " UIViewControllerTransitioningDelegate "
self = an instance of VCA
myModalViewController = is a strong property of self
self.myModalViewController = [[VCB alloc] init];
[self.myModalViewController setModalPresentationStyle: UIModalPresentationCustom];
[self.myModalViewController setTransitioningDelegate: [[TD alloc] init]];
[self presentViewController: self.myModalViewController
animated:YES
completion:NULL];
self = an instance of VCA
myModalViewController = the modally presented instance of VCB presented earlier
[self dismissViewControllerAnimated:YES
completion:^{
[self.myModalViewController setTransitioningDelegate: nil]; // DO THIS!!!!
self.myModalViewController = nil;
}];
I hope this helps. It certainly did for me.
In my case I had self ( UIViewController
) holding an instance of a custom UIViewController
(lets call it mViewController
), and self
is the transitioningDelegate
of showing/dismissing mViewConroller
. My solution to avoid retain-cycle was to call this inside the .m
of mViewController
:
-(void)viewDidDisappear:(BOOL)animated {
self.transitioningDelegate = nil;
[super viewDidDisappear:animated];
}
Worked like a charm (:
In the second try, you are allocating a TransitionController
instance and it will be never released (as nobody has a reference to it). The objects should never retain it's delegates in Objective-C, so you need to have reference to your ViewController
and to it's delegate
from an other point of your code.
The UIViewControllerAnimatedTransitioning
object is retained by the 'from' VC after the transition finishes in iOS7 (this doesn't happen in iOS8) which can cause memory leaks if your transition object stores anything in properties. This bit me in the past, something to be careful of.
In my case, what was causing the retention of my presented view controller was that I was passing the wrong boolean to the completion block of my animation.
[transitionContext completeTransition:transitionContext.transitionWasCancelled];
It should have been this:
BOOL successful = transitionContext.transitionWasCancelled == NO;
[transitionContext completeTransition:successful];
Splitting the code into two lines helps readability.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.