Reputation: 95
I am using a custom Navigation Controller to show and hide two ViewControllers. The code that will call the ViewController to show some movie detail is:
func tapGestureRecognizer(gestureRecognizer: UITapGestureRecognizer){
self.searchBarTop.endEditing(true)
let p = gestureRecognizer.locationInView(self.collectionViewMovies)
let tag = gestureRecognizer.view?.tag
if tag == 1{
if let indexPath : NSIndexPath = (self.collectionViewMovies?.indexPathForItemAtPoint(p)){
if let cell = self.collectionViewMovies.cellForItemAtIndexPath(indexPath){
cellAnimation.imageBlurCell(cell, style: .Light, alpha: 1.0, completion: { (complete) -> Void in
if let record = self.fetchedResultsController.objectAtIndexPath(indexPath) as? Movies{
let movieId = record.movieid as! Int
NSNotificationCenter.defaultCenter().postNotificationName("moviesShouldGetDetails", object: nil, userInfo: ["movieId":movieId])
let destination = self.myStoryboard.instantiateViewControllerWithIdentifier("MovieDetails") as! MovieDetailsViewController
destination.movieId = movieId
self.navigationController?.pushViewController(destination, animated: true)
}
})
}
}
}
}
I am creating a new instance of MovieDetailsViewController every time. The problem is that i thought that after the NavigationController Pop the ViewController the instance would be killed, but this is not happing. I have some Observers inside the MovieDetailsViewController and i can see that the instance still running. The NavigationController delegate is:
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if operation == .Push {
customInteractionController.attachToViewController(toVC)
}
customNavigationAnimationController.reverse = operation == .Pop
return customNavigationAnimationController
}
func navigationController(navigationController: UINavigationController, interactionControllerForAnimationController animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return customInteractionController.transitionInProgress ? customInteractionController : nil
}
The code to control the animation is bellow, i tried to force the Navigation Pop again, when the animation complete, but no luck so far.
import UIKit
class CustomNavigationAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
var reverse = false
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 0.5
}
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView()
let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
let toView = toViewController.view
let fromView = fromViewController.view
let direction: CGFloat = reverse ? -1 : 1
let const: CGFloat = -0.005
toView.layer.anchorPoint = CGPointMake(direction == 1 ? 0 : 1, 0.5)
fromView.layer.anchorPoint = CGPointMake(direction == 1 ? 1 : 0, 0.5)
var viewFromTransform: CATransform3D = CATransform3DMakeRotation(direction * CGFloat(M_PI_2), 0.0, 1.0, 0.0)
var viewToTransform: CATransform3D = CATransform3DMakeRotation(-direction * CGFloat(M_PI_2), 0.0, 1.0, 0.0)
viewFromTransform.m34 = const
viewToTransform.m34 = const
containerView!.transform = CGAffineTransformMakeTranslation(direction * containerView!.frame.size.width / 2.0, 0)
toView.layer.transform = viewToTransform
containerView!.addSubview(toView)
UIView.animateWithDuration(transitionDuration(transitionContext), animations: {
containerView!.transform = CGAffineTransformMakeTranslation(-direction * containerView!.frame.size.width / 2.0, 0)
fromView.layer.transform = viewFromTransform
toView.layer.transform = CATransform3DIdentity
}, completion: {
finished in
containerView!.transform = CGAffineTransformIdentity
fromView.layer.transform = CATransform3DIdentity
toView.layer.transform = CATransform3DIdentity
fromView.layer.anchorPoint = CGPointMake(0.5, 0.5)
toView.layer.anchorPoint = CGPointMake(0.5, 0.5)
if (transitionContext.transitionWasCancelled()) {
toView.removeFromSuperview()
} else {
fromView.removeFromSuperview()
if self.reverse{
print("removing from superview")
fromViewController.navigationController?.popViewControllerAnimated(false)
}
}
transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
})
}
}
What am i missing here ? How can i kill my MovieDetailsViewController instance ? The NavigationController .Pop should not kill the instance form me ? Thanks in advance.
Upvotes: 0
Views: 1008
Reputation: 95
After spend sometime understanding how ARC works i was able to fix the problem. I had some Strong Reference Cycles because of some delegates that was not declared like "weak". The other problem was in this line
customInteractionController.attachToViewController(toVC)
This code will create a Strong Reference with a NavigationViewController in another class, i just change this reference to weak. Now everything is working fine.
Upvotes: 0
Reputation: 2636
You say
I have some Observers inside the MovieDetailsViewController and i can see that the instance still running.
Could that possibly mean that you are retaining references to the MovieDetailsViewController after the pop? Swift's garbage collector will not deallocate the view controller until it no longer has any references. If you maintain references to the view controller it will stay alive even when off screen.
Upvotes: 0