I am trying to add an animated card to my app and I wrote the code below in the view controller , but when I run the project I can not interract with the card
CODE :
import UIKit
class HomeViewController: UIViewController {
enum cardState {
case expanded
case collapsed
}
var goalCard:GoalCardViewController!
var visualBlur:UIVisualEffectView!
let cardHeight:CGFloat = 800
let cardHandleHeight:CGFloat = 110
var cardVisible = false
var nextState:cardState {
return cardVisible ? .collapsed : .expanded
}
var runningAnimations = [UIViewPropertyAnimator]()
var animationInProgressWhenInterrupted:CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
setUpCard()
}
func setUpCard() {
visualBlur = UIVisualEffectView()
visualBlur.frame = self.view.frame
self.view.addSubview(visualBlur)
goalCard = GoalCardViewController(nibName:"GoalCardViewController", bundle:nil)
self.addChild(goalCard)
self.view.addSubview(goalCard.view)
goalCard.view.frame = CGRect(x: 0, y: self.view.frame.height - cardHandleHeight, width: self.view.bounds.width, height: cardHeight)
goalCard.view.clipsToBounds = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(HomeViewController.handleCardTap(recognizer:)))
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(HomeViewController.handleCardPan(recognizer:)))
goalCard.handleArea.addGestureRecognizer(panGestureRecognizer)
goalCard.handleArea.addGestureRecognizer(tapGestureRecognizer)
}
@objc
func handleCardTap (recognizer: UITapGestureRecognizer) {
}
@objc
func handleCardPan (recognizer: UIPanGestureRecognizer) {
switch recognizer.state {
case .began:
// Start Transition
startInteractiveTransition(state: nextState, duration: 0.9)
case .changed:
// Update Transition
let translation = recognizer.translation(in: self.goalCard.view)
var fractionComplete = translation.y / cardHeight
fractionComplete = cardVisible ? fractionComplete : -fractionComplete
updateInteractiveTransition(fractionCompleted: 0)
case .ended:
// Continue Transition
func finishInteractiveTransition() {
for animator in runningAnimations {
animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)
}
}
default:
break
}
}
func animateTransitionIfNeeded (state:cardState, duration:TimeInterval) {
if runningAnimations.isEmpty {
let frameAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) {
switch state {
case .expanded:
self.goalCard.view.frame.origin.y = self.view.frame.height - self.cardHeight
case .collapsed:
self.goalCard.view.frame.origin.y = self.view.frame.height - self.cardHandleHeight
}
}
frameAnimator.addCompletion { _ in self.cardVisible = !self.cardVisible
self.runningAnimations.removeAll()
}
frameAnimator.startAnimation()
runningAnimations.append(frameAnimator)
let cornerRadiusAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) {
switch state {
case .expanded:
self.goalCard.view.layer.cornerRadius = 12.0
case .collapsed:
self.goalCard.view.layer.cornerRadius = 12.0
}
}
cornerRadiusAnimator.startAnimation()
runningAnimations.append(cornerRadiusAnimator)
}
}
func startInteractiveTransition (state:cardState, duration:TimeInterval) {
if runningAnimations.isEmpty {
//run animations
animateTransitionIfNeeded(state: state, duration: duration)
}
for animator in runningAnimations {
animator.pauseAnimation()
animationInProgressWhenInterrupted = animator.fractionComplete
}
}
func updateInteractiveTransition (fractionCompleted:CGFloat) {
for animator in runningAnimations {
animator.fractionComplete = fractionCompleted + animationInProgressWhenInterrupted
}
func finishTransition() {
for animator in runningAnimations {
animator.continueAnimation(withTimingParameters: nil, durationFactor: 0)
}
}
}
}