3

In the following code, I am trying to create a custom animator during navigation transition but the navigation controller delegate method is not getting a call. Please look at the below code and suggest me a solution.

Please note that I have embedded the DemoTransitionAnimationViewController in a navigation controller. This VC has a button on its view. On click of this view I am pushing another view controller. But still the delegate method is not getting a call.

CustomAnimator.swift

//
//  CustomAnimator.swift
//  LoginModule
//
//  Created by Shubham Ojha on 8/14/17.
//  Copyright © 2017 BBI. All rights reserved.
//

class FadeInAnimator: NSObject,
UIViewControllerAnimatedTransitioning {
    func transitionDuration(
        using transitionContext: UIViewControllerContextTransitioning?
        ) -> TimeInterval {
        return 0.35

    }
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let containerView = transitionContext.containerView
        let fromVC = transitionContext.viewController(
            forKey: UITransitionContextViewControllerKey.from)
        let toVC = transitionContext.viewController(
            forKey: UITransitionContextViewControllerKey.to)

        containerView.addSubview(toVC!.view)
        toVC!.view.alpha = 0.0

        let duration = transitionDuration(using: transitionContext)
        UIView.animate(withDuration: duration, animations: {
            toVC!.view.alpha = 1.0
            toVC?.view.backgroundColor = UIColor.blue
        }, completion: { finished in
            let cancelled = transitionContext.transitionWasCancelled
            transitionContext.completeTransition(!cancelled)
        })
    }

}

class NavigationControllerDelegate: NSObject,
UINavigationControllerDelegate {

    func navigationController(
        _ navigationController: UINavigationController,
        animationControllerFor operation:
        UINavigationControllerOperation,
        from fromVC: UIViewController,
        to toVC: UIViewController
        ) -> UIViewControllerAnimatedTransitioning? {

        return FadeInAnimator()

    }
}

DemoTransitionAnimationViewController.swift

//
//  DemoTransitionAnimationViewController.swift
//  LoginModule
//
//  Created by Shubham Ojha on 8/15/17.
//  Copyright © 2017 BBI. All rights reserved.
//

import UIKit

class DemoTransitionAnimationViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        print(self.navigationController ?? "Not exist")

        if self.navigationController != nil{
            self.navigationController?.delegate = NavigationControllerDelegate()
       // In the above statement if I am setting the delegate as self instead of 
      //NavigationControllerDelegate() and conforming the methods of navigation 
      //controller delegate protocol. It works perfectly.
        }
        else{
            print("navigation controller does not exist")
        }

    }

}
Shubham Ojha
  • 461
  • 5
  • 17
  • Try changing class NavigationControllerDelegate inherited from NSObject to UINavigationController. – Aadil Ali Aug 15 '17 at 13:34
  • I tried it but still not getting a call. Below answer from Krunal has solved my problem, But I want to know why I am not getting a call in the current code? I am updating my question. – Shubham Ojha Aug 15 '17 at 13:39
  • Because delegate refers to class where we want functionality to be perfromed rather than assigning new class... as per my understanding. – Aadil Ali Aug 15 '17 at 13:42
  • by setting "self" then what will be roll of NavigationControllerDelegate class?? – Aadil Ali Aug 15 '17 at 13:44
  • I have not only changed it to self but also implemented/conform the delegate methods in the "self" which I had implemented in the NavigationControllerDelegate class. – Shubham Ojha Aug 15 '17 at 13:47

1 Answers1

2

Try this:

if self.navigationController != nil{
   self.navigationController?.delegate = self // Update assignment here
}
else {
    print("navigation controller does not exist")
}

self.navigationController?.delegate = NavigationControllerDelegate() is an independent (without any reference of UIViewController) memory allocation. So, It won't respond to implementation of delegate methods of any view controller.

self.navigationController?.delegate = self tells navigation controller delegate to use reference of view controller DemoTransitionAnimationViewController and consider its implementation for navigation.

Krunal
  • 77,632
  • 48
  • 245
  • 261
  • this has solved my problem, but why I am not getting the call using NavigationControllerDelegate() instead of self. – Shubham Ojha Aug 15 '17 at 13:42
  • I have added simple explanation about my answer – Krunal Aug 15 '17 at 13:48
  • Because the navigation controller delegate is a weak reference, so you create a NavigationControllerDelegate() and assign it and it gets deallocated immediately. If you hold a strong reference to NavigationControllerDelegate() somewhere, it will then work. :-) – bandejapaisa Mar 04 '19 at 14:46