Giter VIP home page Giter VIP logo

rebuild-app-store-transition's Introduction

Rebuilding AppStore Card Like Transition

Check the tutorial here

https://medium.com/@kannolee/rebuilding-appstore-card-like-transition-84a73fc7139b

Introduction

Recreate the card like transition Apple made for the App Store "Today" category. By using collection view + pan gesture recognizer. This project is based on Swift 4.

Here's what it'll look like

Example

Installation

Simply copy and paste TransitionClone.swift to your project, and add UIViewControllerTransitioningDelegate to the Class you're going to use.

Then add the two function above. Here I created an enum called transitionMode for the purpose to tell the code what state of transition we are in, if we’re going to Present than set it to “present”, if dismiss than set it to “dismiss”, simple as that.

let transition = TransitionClone()
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    transition.transitionMode = .present
    
    return transition
}

func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    transition.transitionMode = .dismiss
    
    return transition
}

Don't forget to set the starting frame and ending frame, for example:

transition.startingFrame = CGRect(x: a.minX+15, y: a.minY+15, width: 375 / 414 * view.frame.width - 30, height: 408 / 736 * view.frame.height - 30)
transition.destinationFrame = CGRect(x: 0, y: 0, width: view.frame.width, height: cell.myImage.frame.height * view.frame.width / cell.myImage.frame.width)

For the Pan Gesture, we’re going to use UIPanGestureRecognizer, which includes states like began, changed, ended, etc. It’ll give us the convenience to manipulate the animation ongoing percentage. You’ll get what I’m talking about very soon, but now let’s just add the above code to your destination view controller.

import UIKit.UIGestureRecognizerSubclass
class InstantPanGestureRecognizer: UIPanGestureRecognizer {

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
    if (self.state == UIGestureRecognizerState.began) { return }
    super.touchesBegan(touches, with: event)
    self.state = UIGestureRecognizerState.began
    }
}

Create the shrinking animation when draging on the Image, notice that we’re not going to use UIView.animate here because UIViewPropertyAnimator has the advantage to pause and resume the animation. You might be thinking why do we need to pause and resume the animation? Because we want the animation to interact with user’s finger! Which in other word to ““follow”” the finger.

var animator = UIViewPropertyAnimator()
func shrinkAnimation(){
    animator = UIViewPropertyAnimator(duration: 1.0, curve: .easeOut, animations: {
        self.view.transform = CGAffineTransform(scaleX: 0.85, y: 0.85)
        self.view.layer.cornerRadius = 15
    })
    animator.startAnimation()
}

Create a gesture recognizer and add to a UIView, I added on a button but it's ok to add it on the imageView

let recognizer = InstantPanGestureRecognizer(target: self, action: #selector(panRecognizer))
dismissButton.addGestureRecognizer(recognizer)

Create the panRecognizer, and it should work fine. Here’s what do the magic trick, by pausing the animation immediately after starting, we’re now in case .changed, we then track the vertical distance the finger drag from it’s initial place(if you want to track horizontal distance, just change translation.y ⇢ translation.x). Than add it to the current animation process(animator.fractionComplete). For a single tap recognition it’s even easier, there’s no need to add another tap recognizer. Just add an if statement in recognizer.state = ended see the code above :)

var animationProgress: CGFloat = 0.0
@objc func panRecognizer(recognizer: UIPanGestureRecognizer){
    let translation = recognizer.translation(in: dismissButton)
    switch recognizer.state{
    case .began:
        shrinkAnimation()
        animationProgress = animator.fractionComplete
        // Pause after Start enable User to interact with the animation
        animator.pauseAnimation()
    case .changed:
        // translation.y = the distance finger drag on screen
        let fraction = translation.y / 100
        // fractionComplete the percentage of animation progress
        animator.fractionComplete = fraction + animationProgress
        // when animation progress > 99%, stop and start the dismiss transition
        if animator.fractionComplete > 0.99{
            animator.stopAnimation(true)
            dismiss(animated: true, completion: nil)
        }
    case .ended:
        // when tap  on the screen animator.fractionComplete = 0
        if animator.fractionComplete == 0{
            animator.stopAnimation(true)
            dismiss(animated: true, completion: nil)
        }
        // when animator.fractionComplete < 99 % and release finger, automative rebounce to the initial state
        else{
            // rebounce effect
            animator.isReversed = true
            animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)
        }
    default:
        break
    }
}

Special Thanks

Icons made by Freepik from www.flaticon.com is licensed by CC 3.0 BY

rebuild-app-store-transition's People

Contributors

arnoldlee850807 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.