相册打开、关闭图片动画
2022-04-20 本文已影响0人
_浅墨_
最终效果:
主要代码:
PresentAnimator.swift:
import Foundation
import UIKit
class PresentAnimator: NSObject, UIViewControllerAnimatedTransitioning {
var originFrame = CGRect.zero
var offset: CGFloat = 0
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.5
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
let detailView = transitionContext.view(forKey: UITransitionContextViewKey.to)!
let finalFrame = detailView.frame
var initialFrame = originFrame
let detailAspectRatio = finalFrame.width / finalFrame.height
initialFrame.size = CGSize(width: initialFrame.width, height: initialFrame.width / detailAspectRatio)
let scaleFactor = finalFrame.width / initialFrame.width
let growScaleFactor = scaleFactor
let shrinkScaleFactor = 1 / growScaleFactor
detailView.transform = CGAffineTransform(scaleX: shrinkScaleFactor, y: shrinkScaleFactor)
detailView.center = CGPoint(
x: originFrame.midX,
y: originFrame.midY + offset
)
detailView.clipsToBounds = true
containerView.addSubview(detailView)
UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 1, options: [.curveEaseIn], animations: {
detailView.transform = CGAffineTransform.identity
detailView.center = CGPoint(
x: finalFrame.midX,
y: finalFrame.midY
)
}) { (success) in
transitionContext.completeTransition(
!transitionContext.transitionWasCancelled
)
}
}
}
DismissAnimator.swift:
import Foundation
import UIKit
class DismissAnimator: NSObject, UIViewControllerAnimatedTransitioning {
var offset: CGFloat = 0
var originFrame = CGRect.zero
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.2
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
let detailView = transitionContext.view(forKey: UITransitionContextViewKey.from)!
let thumbnailView = transitionContext.view(forKey: UITransitionContextViewKey.to)!
let finalFrame = originFrame
let initialFrame = detailView.frame
let scaleFactor = initialFrame.width / finalFrame.width
let growScaleFactor = scaleFactor
let shrinkScaleFactor = 1 / growScaleFactor
detailView.clipsToBounds = true
containerView.addSubview(thumbnailView)
containerView.bringSubviewToFront(detailView)
detailView.backgroundColor = UIColor.clear
UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0, options: [], animations: {
detailView.transform = CGAffineTransform(scaleX: shrinkScaleFactor, y: shrinkScaleFactor)
detailView.center = CGPoint(
x: finalFrame.midX,
y: finalFrame.midY + self.offset
)
}) { (success) in
transitionContext.completeTransition(
!transitionContext.transitionWasCancelled
)
}
}
}
使用方法:
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var collectionView: UICollectionView!
var selectedCell = UICollectionViewCell()
let dataCount:Int = 12
var offset: CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
collectionView.delegate = self
collectionView.dataSource = self
self.navigationController?.delegate = self
offset = self.navigationController!.navigationBar.frame.height + UIApplication.shared.statusBarFrame.size.height
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataCount
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "imagecell", for: indexPath) as! ImageCollectionViewCell
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
selectedCell = collectionView.cellForItem(at: indexPath)!
performSegue(withIdentifier: "NewVCSegue", sender: nil)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemsPerRow:CGFloat = 3
let hardCodedPadding:CGFloat = 2
let itemWidth = (collectionView.bounds.width / itemsPerRow) - hardCodedPadding
let itemHeight = itemWidth
return CGSize(width: itemWidth, height: itemHeight)
}
}
extension ViewController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
switch operation {
case .push:
let animator = PresentAnimator()
animator.originFrame = selectedCell.frame
animator.offset = offset
return animator
case .pop:
let animator = DismissAnimator()
animator.originFrame = selectedCell.frame
animator.offset = offset
return animator
default:
return nil
}
}
}