iOS开发

相册打开、关闭图片动画

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
            
        }    
    }
        
}

源码下载:

上一篇下一篇

猜你喜欢

热点阅读