Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
NotificationsYou must be signed in to change notification settings

arnoldlee850807/Rebuild-App-Store-Transition

Repository files navigation

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.UIGestureRecognizerSubclassclass 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 byFreepik fromwww.flaticon.com is licensed byCC 3.0 BY

About

No description or website provided.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp