Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace pop with UIView animations #472

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cartfile

This file was deleted.

1 change: 0 additions & 1 deletion Cartfile.resolved

This file was deleted.

4 changes: 2 additions & 2 deletions Example/Koloda.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,10 @@
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Koloda_Example/Pods-Koloda_Example-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/Koloda/Koloda.framework",
"${BUILT_PRODUCTS_DIR}/pop/pop.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Koloda.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/pop.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
Expand Down Expand Up @@ -404,6 +402,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
INFOPLIST_FILE = Koloda/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "com.yalantis.Koloda-Example";
Expand All @@ -420,6 +419,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
INFOPLIST_FILE = Koloda/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "com.yalantis.Koloda-Example";
Expand Down
8 changes: 2 additions & 6 deletions Example/Koloda/BackgroundAnimationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import UIKit
import Koloda
import pop

private let numberOfCards: Int = 5
private let frameAnimationSpringBounciness: CGFloat = 9
Expand Down Expand Up @@ -70,11 +69,8 @@ extension BackgroundAnimationViewController: KolodaViewDelegate {
return true
}

func koloda(kolodaBackgroundCardAnimation koloda: KolodaView) -> POPPropertyAnimation? {
let animation = POPSpringAnimation(propertyNamed: kPOPViewFrame)
animation?.springBounciness = frameAnimationSpringBounciness
animation?.springSpeed = frameAnimationSpringSpeed
return animation
func koloda(kolodaBackgroundCardAnimation koloda: KolodaView) -> UIViewPropertyAnimator? {
return UIViewPropertyAnimator(duration: 0.2, dampingRatio: (frameAnimationSpringBounciness - 20) / 20, animations: nil)
}
}

Expand Down
23 changes: 8 additions & 15 deletions Example/Koloda/BackgroundKolodaAnimator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,21 @@

import Foundation
import Koloda
import pop

class BackgroundKolodaAnimator: KolodaViewAnimator {

override func applyScaleAnimation(_ card: DraggableCardView, scale: CGSize, frame: CGRect, duration: TimeInterval, completion: AnimationCompletionBlock) {

let scaleAnimation = POPSpringAnimation(propertyNamed: kPOPLayerScaleXY)
scaleAnimation?.springBounciness = 9
scaleAnimation?.springSpeed = 16
scaleAnimation?.toValue = NSValue(cgSize: scale)
card.layer.pop_add(scaleAnimation, forKey: "scaleAnimation")

let frameAnimation = POPSpringAnimation(propertyNamed: kPOPViewFrame)
frameAnimation?.springBounciness = 9
frameAnimation?.springSpeed = 16
frameAnimation?.toValue = NSValue(cgRect: frame)

let animation = UIViewPropertyAnimator(duration: duration, dampingRatio: 0.7) {
card.transform = CGAffineTransform(scaleX: scale.width, y: scale.height)
card.frame = frame
}
if let completion = completion {
frameAnimation?.completionBlock = { _, finished in
completion(finished)
animation.addCompletion { position in
completion(position == .end)
}
}
card.pop_add(frameAnimation, forKey: "frameAnimation")
animation.startAnimation()
}

}
2 changes: 2 additions & 0 deletions Example/Podfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
platform :ios, '10.0'

source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!

Expand Down
5 changes: 2 additions & 3 deletions Koloda.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'Koloda'
s.version = '5.0.1'
s.version = '5.0.2'
s.summary = 'KolodaView is a class designed to simplify the implementation of Tinder like cards on iOS. '

s.homepage = 'https://github.com/Yalantis/Koloda'
Expand All @@ -9,9 +9,8 @@ Pod::Spec.new do |s|
s.source = { :git => 'https://github.com/Yalantis/Koloda.git', :tag => s.version }
s.social_media_url = 'https://twitter.com/yalantis'

s.platform = :ios, '8.0'
s.platform = :ios, '10.0'
s.source_files = 'Pod/Classes/**/*'

s.frameworks = 'UIKit'
s.dependency 'pop', '~> 1.0'
end
3 changes: 3 additions & 0 deletions Koloda.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
);
mainGroup = C517E4A11D9CF9010002D88F;
Expand Down Expand Up @@ -328,6 +329,7 @@
);
INFOPLIST_FILE = Pod/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.cocoapods.Koloda;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -350,6 +352,7 @@
);
INFOPLIST_FILE = Pod/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.cocoapods.Koloda;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
82 changes: 23 additions & 59 deletions Pod/Classes/KolodaView/DraggableCardView/DraggableCardView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//

import UIKit
import pop

public enum DragSpeed: TimeInterval {
case slow = 2.0
Expand Down Expand Up @@ -378,89 +377,54 @@ public class DraggableCardView: UIView, UIGestureRecognizerDelegate {
overlayView?.overlayState = direction
overlayView?.alpha = 1.0
delegate?.card(self, wasSwipedIn: direction)
let translationAnimation = POPBasicAnimation(propertyNamed: kPOPLayerTranslationXY)
translationAnimation?.duration = cardSwipeActionAnimationDuration
translationAnimation?.fromValue = NSValue(cgPoint: POPLayerGetTranslationXY(layer))
translationAnimation?.toValue = NSValue(cgPoint: animationPointForDirection(direction))
translationAnimation?.completionBlock = { _, _ in

UIViewPropertyAnimator.runningPropertyAnimator(withDuration: cardSwipeActionAnimationDuration, delay: 0, options: []) {
let point = self.animationPointForDirection(direction)
self.transform = CGAffineTransform(translationX: point.x, y: point.y)
} completion: { position in
self.removeFromSuperview()
}
layer.pop_add(translationAnimation, forKey: "swipeTranslationAnimation")
}

private func resetViewPositionAndTransformations() {
delegate?.card(cardWasReset: self)

removeAnimations()

let resetPositionAnimation = POPSpringAnimation(propertyNamed: kPOPLayerTranslationXY)
resetPositionAnimation?.fromValue = NSValue(cgPoint:POPLayerGetTranslationXY(layer))
resetPositionAnimation?.toValue = NSValue(cgPoint: CGPoint.zero)
resetPositionAnimation?.springBounciness = cardResetAnimationSpringBounciness
resetPositionAnimation?.springSpeed = cardResetAnimationSpringSpeed
resetPositionAnimation?.completionBlock = {
(_, _) in

UIView.animate(withDuration: cardResetAnimationDuration, delay: 0, usingSpringWithDamping: (20 - cardResetAnimationSpringBounciness) / 20, initialSpringVelocity: cardResetAnimationSpringSpeed * 2, options: []) {
self.transform = .identity
} completion: { _ in
self.layer.transform = CATransform3DIdentity
self.dragBegin = false
}

layer.pop_add(resetPositionAnimation, forKey: "resetPositionAnimation")

let resetRotationAnimation = POPBasicAnimation(propertyNamed: kPOPLayerRotation)
resetRotationAnimation?.fromValue = POPLayerGetRotationZ(layer)
resetRotationAnimation?.toValue = CGFloat(0.0)
resetRotationAnimation?.duration = cardResetAnimationDuration

layer.pop_add(resetRotationAnimation, forKey: "resetRotationAnimation")

let overlayAlphaAnimation = POPBasicAnimation(propertyNamed: kPOPViewAlpha)
overlayAlphaAnimation?.toValue = 0.0
overlayAlphaAnimation?.duration = cardResetAnimationDuration
overlayAlphaAnimation?.completionBlock = { _, _ in

UIViewPropertyAnimator.runningPropertyAnimator(withDuration: cardResetAnimationDuration, delay: 0, options: []) {
self.overlayView?.alpha = 0
} completion: { position in
self.overlayView?.alpha = 0
}
overlayView?.pop_add(overlayAlphaAnimation, forKey: "resetOverlayAnimation")

let resetScaleAnimation = POPBasicAnimation(propertyNamed: kPOPLayerScaleXY)
resetScaleAnimation?.toValue = NSValue(cgPoint: CGPoint(x: 1.0, y: 1.0))
resetScaleAnimation?.duration = cardResetAnimationDuration
layer.pop_add(resetScaleAnimation, forKey: "resetScaleAnimation")
}

//MARK: Public
func removeAnimations() {
pop_removeAllAnimations()
layer.pop_removeAllAnimations()
layer.removeAllAnimations()
}

func swipe(_ direction: SwipeResultDirection, completionHandler: @escaping () -> Void) {
if !dragBegin {
delegate?.card(self, wasSwipedIn: direction)

let swipePositionAnimation = POPBasicAnimation(propertyNamed: kPOPLayerTranslationXY)
swipePositionAnimation?.fromValue = NSValue(cgPoint:POPLayerGetTranslationXY(layer))
swipePositionAnimation?.toValue = NSValue(cgPoint:animationPointForDirection(direction))
swipePositionAnimation?.duration = cardSwipeActionAnimationDuration
swipePositionAnimation?.completionBlock = {
(_, _) in

overlayView?.overlayState = direction

UIViewPropertyAnimator.runningPropertyAnimator(withDuration: cardSwipeActionAnimationDuration, delay: 0, options: []) {
let point = self.animationPointForDirection(direction)
self.transform = CGAffineTransform(translationX: point.x, y: point.y)
.rotated(by: self.animationRotationForDirection(direction))
self.overlayView?.alpha = 1
} completion: { position in
self.removeFromSuperview()
completionHandler()
}

layer.pop_add(swipePositionAnimation, forKey: "swipePositionAnimation")

let swipeRotationAnimation = POPBasicAnimation(propertyNamed: kPOPLayerRotation)
swipeRotationAnimation?.fromValue = POPLayerGetRotationZ(layer)
swipeRotationAnimation?.toValue = CGFloat(animationRotationForDirection(direction))
swipeRotationAnimation?.duration = cardSwipeActionAnimationDuration

layer.pop_add(swipeRotationAnimation, forKey: "swipeRotationAnimation")

overlayView?.overlayState = direction
let overlayAlphaAnimation = POPBasicAnimation(propertyNamed: kPOPViewAlpha)
overlayAlphaAnimation?.toValue = 1.0
overlayAlphaAnimation?.duration = cardSwipeActionAnimationDuration
overlayView?.pop_add(overlayAlphaAnimation, forKey: "swipeOverlayAnimation")
}
}
}
1 change: 0 additions & 1 deletion Pod/Classes/KolodaView/KolodaView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//

import UIKit
import pop

// Default values
private let defaultCountOfVisibleCards = 3
Expand Down
92 changes: 36 additions & 56 deletions Pod/Classes/KolodaView/KolodaViewAnimatior.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import Foundation
import UIKit
import pop

open class KolodaViewAnimator {

Expand All @@ -21,78 +20,59 @@ open class KolodaViewAnimator {
}

open func animateAppearance(_ duration: TimeInterval, completion: AnimationCompletionBlock = nil) {
let kolodaAppearScaleAnimation = POPBasicAnimation(propertyNamed: kPOPLayerScaleXY)

kolodaAppearScaleAnimation?.beginTime = CACurrentMediaTime() + cardSwipeActionAnimationDuration
kolodaAppearScaleAnimation?.duration = duration
kolodaAppearScaleAnimation?.fromValue = NSValue(cgPoint: CGPoint(x: 0.1, y: 0.1))
kolodaAppearScaleAnimation?.toValue = NSValue(cgPoint: CGPoint(x: 1.0, y: 1.0))
kolodaAppearScaleAnimation?.completionBlock = { (_, finished) in
completion?(finished)

koloda?.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
koloda?.alpha = 0

UIViewPropertyAnimator.runningPropertyAnimator(withDuration: duration, delay: cardSwipeActionAnimationDuration, options: []) {
self.koloda?.transform = CGAffineTransform(scaleX: 1, y: 1)
} completion: { position in
completion?(position == .end)
}

let kolodaAppearAlphaAnimation = POPBasicAnimation(propertyNamed: kPOPViewAlpha)

kolodaAppearAlphaAnimation?.beginTime = CACurrentMediaTime() + cardSwipeActionAnimationDuration
kolodaAppearAlphaAnimation?.fromValue = NSNumber(value: 0.0)
kolodaAppearAlphaAnimation?.toValue = NSNumber(value: 1.0)
kolodaAppearAlphaAnimation?.duration = duration

koloda?.pop_add(kolodaAppearAlphaAnimation, forKey: "kolodaAppearScaleAnimation")
koloda?.layer.pop_add(kolodaAppearScaleAnimation, forKey: "kolodaAppearAlphaAnimation")
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: duration, delay: cardSwipeActionAnimationDuration, options: []) {
self.koloda?.alpha = 1
}
}

open func applyReverseAnimation(_ card: DraggableCardView, direction: SwipeResultDirection?, duration: TimeInterval, completion: AnimationCompletionBlock = nil) {
let alphaAnimation = POPBasicAnimation(propertyNamed: kPOPViewAlpha)
alphaAnimation?.fromValue = NSNumber(value: 0.0)
alphaAnimation?.toValue = NSNumber(value: 1.0)
alphaAnimation?.duration = direction != nil ? duration : 1.0
alphaAnimation?.completionBlock = { _, finished in
completion?(finished)

card.alpha = 0

UIViewPropertyAnimator.runningPropertyAnimator(withDuration: direction != nil ? duration : 1.0, delay: 0, options: []) {
card.alpha = 1
} completion: { position in
completion?(position == .end)
card.alpha = 1.0
}
card.pop_add(alphaAnimation, forKey: "reverseCardAlphaAnimation")

guard let direction = direction else { return }

let translationAnimation = POPBasicAnimation(propertyNamed: kPOPLayerTranslationXY)
translationAnimation?.fromValue = NSValue(cgPoint: card.animationPointForDirection(direction))
translationAnimation?.toValue = NSValue(cgPoint: CGPoint.zero)
translationAnimation?.duration = duration
card.layer.pop_add(translationAnimation, forKey: "reverseCardTranslationAnimation")

let rotationAnimation = POPBasicAnimation(propertyNamed: kPOPLayerRotation)
rotationAnimation?.fromValue = CGFloat(card.animationRotationForDirection(direction))
rotationAnimation?.toValue = CGFloat(0.0)
rotationAnimation?.duration = duration
card.layer.pop_add(rotationAnimation, forKey: "reverseCardRotationAnimation")

let animationPoint = card.animationPointForDirection(direction)
let animationRotation = card.animationRotationForDirection(direction)
card.transform = CGAffineTransform(translationX: animationPoint.x, y: animationPoint.y)
.rotated(by: animationRotation)

UIViewPropertyAnimator.runningPropertyAnimator(withDuration: duration, delay: 0, options: []) {
card.transform = .identity
}
}

open func applyScaleAnimation(_ card: DraggableCardView, scale: CGSize, frame: CGRect, duration: TimeInterval, completion: AnimationCompletionBlock = nil) {
let scaleAnimation = POPBasicAnimation(propertyNamed: kPOPLayerScaleXY)
scaleAnimation?.duration = duration
scaleAnimation?.toValue = NSValue(cgSize: scale)
card.layer.pop_add(scaleAnimation, forKey: "scaleAnimation")

let frameAnimation = POPBasicAnimation(propertyNamed: kPOPViewFrame)
frameAnimation?.duration = duration
frameAnimation?.toValue = NSValue(cgRect: frame)
if let completion = completion {
frameAnimation?.completionBlock = { _, finished in
completion(finished)
}
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: duration, delay: 0, options: []) {
card.transform = CGAffineTransform(scaleX: scale.width, y: scale.height)
card.frame = frame
} completion: { position in
completion?(position == .end)
}
card.pop_add(frameAnimation, forKey: "frameAnimation")
}

open func applyAlphaAnimation(_ card: DraggableCardView, alpha: CGFloat, duration: TimeInterval = 0.2, completion: AnimationCompletionBlock = nil) {
let alphaAnimation = POPBasicAnimation(propertyNamed: kPOPViewAlpha)
alphaAnimation?.toValue = alpha
alphaAnimation?.duration = duration
alphaAnimation?.completionBlock = { _, finished in
completion?(finished)
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: duration, delay: 0, options: []) {
card.alpha = alpha
} completion: { position in
completion?(position == .end)
}
card.pop_add(alphaAnimation, forKey: "alpha")
}

open func applyInsertionAnimation(_ cards: [DraggableCardView], completion: AnimationCompletionBlock = nil) {
Expand Down