【Swift】模態檢視的動畫展示
阿新 • • 發佈:2019-01-06
1、業務需求:點選按鈕,自定義一個模態動畫,動畫大概,把上個介面一分為二,從中間分離然後顯示模態出來的介面
import UIKit
// 列舉:present、dismiss的動畫區分
enum CNPresentOneTransitionType {
case Present // 管理present動畫
case Dismiss // 管理dismiss動畫
}
class CNPresnetOneTransition: NSObject,UIViewControllerAnimatedTransitioning {
var typeT : CNPresentOneTransitionType!
init(transitionType:CNPresentOneTransitionType) {
super.init ()
typeT = transitionType
}
// 動畫時間
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.25
}
// 做動畫需要的前後兩個檢視
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
switch typeT! {
case CNPresentOneTransitionType.Present :
presentAnimation(transitionContext: transitionContext)
case CNPresentOneTransitionType.Dismiss:
dismissAnimation(transitionContext: transitionContext)
default:
break
}
}
// 實現present動畫邏輯程式碼
func presentAnimation(transitionContext : UIViewControllerContextTransitioning){
let fromVC = transitionContext.viewController (forKey: UITransitionContextViewControllerKey.from)
if fromVC!.isKind(of: UINavigationController.self){
print("sssss")
}
let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) as! UINavigationController
if toVC.isKind(of: UINavigationController.self){
print("hhhh")
}
let contentView = transitionContext.containerView
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
var rect0 : CGRect!
var rect1 : CGRect!
rect0 = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight/2)
rect1 = CGRect(x: 0, y: screenHeight/2, width: screenWidth, height: screenWidth)
let image0 = imageFromView(view:(fromVC?.view)!, atFrame: rect0)
let image1 = imageFromView(view: (fromVC?.view)!, atFrame: rect1)
let imageView0 = UIImageView(image: image0)
let imageView1 = UIImageView(image: image1)
// contentView.addSubview((fromVC?.view)!)
contentView.addSubview(toVC.view)
contentView.addSubview(imageView0)
contentView.addSubview(imageView1)
UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: {
imageView0.layer.transform = CATransform3DMakeTranslation(0, -screenHeight / 2, 0)
imageView1.layer.transform = CATransform3DMakeTranslation(0, screenHeight / 2, 0)
}) { (isSuccess) in
transitionContext.completeTransition(true)
imageView0.removeFromSuperview()
imageView1.removeFromSuperview()
}
}
//實現dismiss動畫邏輯程式碼
func dismissAnimation(transitionContext : UIViewControllerContextTransitioning){
let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
let contentView = transitionContext.containerView
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
var rect0 : CGRect!
var rect1 : CGRect!
rect0 = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight/2)
rect1 = CGRect(x: 0, y: screenHeight/2, width: screenWidth, height: screenWidth)
let image0 = imageFromView(view: (toVC?.view)!, atFrame: rect0)
let image1 = imageFromView(view: (toVC?.view)!, atFrame: rect1)
let imageView0 = UIImageView(image: image0)
let imageView1 = UIImageView(image: image1)
// contentView.addSubview((fromVC?.view)!)
// contentView.addSubview((toVC?.view)!)
contentView.addSubview(imageView0)
contentView.addSubview(imageView1)
toVC?.view.isHidden = true
imageView0.layer.transform = CATransform3DMakeTranslation(0, -screenHeight / 2, 0)
imageView1.layer.transform = CATransform3DMakeTranslation(0, screenHeight / 2, 0)
UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: {
imageView0.layer.transform = CATransform3DIdentity
imageView1.layer.transform = CATransform3DIdentity
}) { (isSuccess) in
transitionContext.completeTransition(true)
toVC?.view.isHidden = false
imageView0.removeFromSuperview()
imageView1.removeFromSuperview()
}
}
/// 截圖
///
/// - Parameters:
/// - view: view
/// - atFrame: rect
func imageFromView(view : UIView,atFrame:CGRect) -> UIImage {
UIGraphicsBeginImageContext(view.frame.size)
let context = UIGraphicsGetCurrentContext()
context?.saveGState()
UIRectClip(atFrame)
view.layer.render(in: context!)
let theImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return theImage!
}
}
用法:
在你模態出來的那個介面先實現代理
UIViewControllerTransitioningDelegate
並在viewDidLoad裡面實現
self.navigationController?.modalPresentationStyle = .custom
self.navigationController?.transitioningDelegate = self
最後實現兩個代理
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return CNPresnetOneTransition(transitionType: CNPresentOneTransitionType.Present)
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return CNPresnetOneTransition(transitionType: CNPresentOneTransitionType.Dismiss)
}