通过UIViewControllerAnimatedTransitioning实现图片的转场动画,效果类似手机自带的照片查看器。详细过程如下:
先看看效果:
首先造一个ShowImageController控制器
class ShowImageController: UIViewController {
}
那么它能做什么,首先要能展示图片,给它一个UIImageView
class ShowImageController: UIViewController {
/// 图像视图
private lazy var imageView: UIImageView = {
let iv = UIImageView()
return iv
}()
}
其次,它还要支持缩放,给它一个UIScrollView
class ShowImageController: UIViewController {
/// 图像视图
private lazy var imageView: UIImageView = {
let iv = UIImageView()
return iv
}()
/// 滚动视图
private lazy var scrollView: UIScrollView = {
let s = UIScrollView(frame: self.view.bounds)
s.backgroundColor = UIColor.black
// 支持缩放
// 1. 设置代理
s.delegate = self
// 2. 最小大缩放比例
s.minimumZoomScale = 1
s.maximumZoomScale = 2.0
return s
}()
}
添加一个构造方法
- 捕捉一个屏幕快照dummyView
- 设置transitioningDelegate
init(sourceView:UIImageView) {
super.init(nibName: nil, bundle: nil)
self.setImage(image: sourceView.image)
let window = UIApplication.shared.keyWindow
self.showPicDelegate.dummyView = sourceView.snapshotView(afterScreenUpdates: false)
self.showPicDelegate.sourceRect = sourceView.convert(sourceView.bounds, to: window)
self.showPicDelegate.destRect = imageSize(sourceView.image!)
self.transitioningDelegate = self.showPicDelegate
modalPresentationStyle = UIModalPresentationStyle.custom
}
然后实现transitioningDelegate,新建ShowPicAnimator类,添加属性
class ShowPicAnimator: NSObject, UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning {
///是开始还是结束
var isPresent: Bool = true
///快照
var dummyView: UIView?
///起始位置
var sourceRect: CGRect = CGRect.zero
///结束位置
var destRect: CGRect = CGRect.zero
}
添加代理方法
// 指定谁负责转场动画
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
isPresent = true
return self
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
isPresent = false
return self
}
//UIViewControllerAnimatedTransitioning
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.3
}
/* self实现动画
1. 计算动画的起始位置
2. 计算动画的目标位置
*/
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
}
具体实现细节见代码