Skip to content

Instantly share code, notes, and snippets.

@Coder-ACJHP
Created October 22, 2024 13:12
Show Gist options
  • Save Coder-ACJHP/20ddb009ba0aee7e72d1a9870312e81a to your computer and use it in GitHub Desktop.
Save Coder-ACJHP/20ddb009ba0aee7e72d1a9870312e81a to your computer and use it in GitHub Desktop.
3DFlipScaleAnimation any UIView using Swift UIKit (tested on iOS 12 and later)
class AnimationsTestViewController: UIViewController {
enum AnimationPosiXDirection {
case left, center, right
}
enum AnimationFlipDirection {
case yAxis, center, xAxis
}
private let containerView: UIView = {
let view = UIView(frame: .zero)
view.backgroundColor = .white
view.layer.cornerRadius = 16
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
configureContentView()
}
private func configureContentView() {
view.addSubview(containerView)
NSLayoutConstraint.activate([
containerView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
containerView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
containerView.widthAnchor.constraint(equalToConstant: 200),
containerView.heightAnchor.constraint(equalToConstant: 170)
])
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
animateRotate3DFlip(from: .right, direction: .xAxis, rotationCount: 3)
}
private func animateRotate3DFlip(from: AnimationPosiXDirection, direction: AnimationFlipDirection, centerLeftToRight: Bool = false, rotationCount: CGFloat = 1) {
prepareScale3DAnimation(from: from)
start3DFlipAnimationWith(direction: direction, centerLeftToRight: centerLeftToRight, rotationCount: rotationCount)
}
private func prepareScale3DAnimation(from: AnimationPosiXDirection) {
var perspective = CATransform3DIdentity
switch from {
case .left:
perspective.m34 = 1 / -200
case .center:
perspective.m34 = 0 / -200
case .right:
perspective.m34 = -1 / -200
}
containerView.layer.transform = perspective
}
private func start3DFlipAnimationWith(direction: AnimationFlipDirection, centerLeftToRight: Bool = false, rotationCount: CGFloat = 1) {
var rotateAnimation: CABasicAnimation!
switch direction {
case .xAxis:
rotateAnimation = CABasicAnimation(keyPath: "transform.rotation.y")
case .center:
rotateAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
case .yAxis:
rotateAnimation = CABasicAnimation(keyPath: "transform.rotation.x")
}
rotateAnimation.fromValue = 0
let directionAndTimes = CGFloat.pi * rotationCount
rotateAnimation.byValue = centerLeftToRight ? directionAndTimes : -directionAndTimes
rotateAnimation.duration = 1
rotateAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
// add animation
containerView.layer.add(rotateAnimation, forKey: "3Dflip")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment