2

I found this article to create a navigation transition like the Apple news app: https://blog.rocketinsights.com/how-to-create-a-navigation-transition-like-the-apple-news-app/.

The transition is a zoom effect.

The code works great for push animation, but for pop animation (to close DetailViewController), I have a black screen instead my main viewcontroller.

As the article doesn't provide the full source code to download, I publish it on github, apply to UICollectionViewController for my needs: testZoomTransition

enter image description here

cmii
  • 3,556
  • 8
  • 38
  • 69
  • 1
    Your link to your test project is just an empty basic iOS project. There's no custom code in it. – digitalHound Jul 31 '18 at 17:24
  • Sorry for that, project is updated now. – cmii Aug 01 '18 at 12:19
  • It's great that you provided a link to a test project, but you should also show the relevant part of your code _in the question_. Your answer is kind of useless because we don't know what the code was _before_ you made whatever the changes are. – matt Aug 01 '18 at 16:13
  • Also, do you really mean push and pop? This looks more like present and dismiss. For push and pop, I would expect to see a navigation bar. – matt Aug 01 '18 at 16:15
  • Yes I need push and pop, I posted my solution below. – cmii Aug 01 '18 at 17:05

1 Answers1

3

I found a solution, by simplifying the source code, maybe less elegant, but effective.

Git is updated.

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    let presenting = operation == .push

    // Determine which is the master view and which is the detail view that we're navigating to and from. The container view will house the views for transition animation.
    let containerView = transitionContext.containerView

    guard let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from),
        let toView = transitionContext.view(forKey: UITransitionContextViewKey.to) else {
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
            return
    }

    containerView.backgroundColor = fromView.backgroundColor

    let mainView = presenting ? fromView : toView
    let detailView = presenting ? toView : fromView

    // Determine the starting frame of the detail view for the animation. When we're presenting, the detail view will grow out of the thumbnail frame. When we're dismissing, the detail view will shrink back into that same thumbnail frame.
    let finalFrame = presenting ? detailView.frame : thumbnailFrame

    //scale factor between thumbnailFrame and size of
    let scaleFactorX = thumbnailFrame.size.width / detailView.frame.size.width
    let scaleFactorY = thumbnailFrame.size.height / detailView.frame.size.height

    if presenting {

        // Shrink the detail view for the initial frame. The detail view will be scaled to CGAffineTransformIdentity below.
        detailView.transform = CGAffineTransform(scaleX: scaleFactorX, y: scaleFactorY)
        detailView.center = CGPoint(x: thumbnailFrame.midX, y: thumbnailFrame.midY)
        detailView.clipsToBounds = true
    }


    // Set the initial state of the alpha for the master and detail views so that we can fade them in and out during the animation.
    detailView.alpha = presenting ? 0 : 1
    mainView.alpha = presenting ? 1 : 0

    // Add the view that we're transitioning to to the container view that houses the animation.
    containerView.addSubview(toView)
    containerView.bringSubview(toFront: detailView)


    // Animate the transition.
    UIView.animate(withDuration: duration, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 1.0, options: .curveEaseInOut, animations: {
        // Fade the master and detail views in and out.
        detailView.alpha = presenting ? 1 : 0
        mainView.alpha = presenting ? 0 : 1

        if presenting {
            detailView.transform = CGAffineTransform.identity
            detailView.center = CGPoint(x: finalFrame.midX, y: finalFrame.midY)
        }
        else {
            detailView.transform = CGAffineTransform(scaleX: scaleFactorX, y: scaleFactorY)
            detailView.center = CGPoint(x: self.thumbnailFrame.midX, y: self.thumbnailFrame.midY)
        }


    }) { finished in
        transitionContext.completeTransition(finished)
    }
}
cmii
  • 3,556
  • 8
  • 38
  • 69
  • The starting animation seems slow to me compared to the picture you've showied in the original post. When I tap there seems to be around a second delay in the animation from when I tap the cell to when the animation starts. Did you have to make any changes in addition to this one? – wxcoder Dec 30 '20 at 03:32