162 lines
6.9 KiB
Swift
162 lines
6.9 KiB
Swift
//
|
|
// GYSideAnimatedTransitioning.swift
|
|
// GYSide
|
|
//
|
|
// Created by gaoyuan on 2018/1/29.
|
|
// Copyright © 2018年 gaoyuan. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
enum GYSideShowType:Int {
|
|
case show,hidden
|
|
}
|
|
|
|
class GYSideAnimatedTransitioning: NSObject,UIViewControllerAnimatedTransitioning {
|
|
|
|
var type:GYSideShowType!
|
|
var config:GYSideConfig!
|
|
|
|
init(showType: GYSideShowType,config: GYSideConfig) {
|
|
self.type = showType
|
|
self.config = config
|
|
}
|
|
|
|
// 执行的动画时长
|
|
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
|
|
config.timeInterval
|
|
}
|
|
|
|
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
|
|
switch type {
|
|
case .show?:
|
|
animateTransitionShowType(transitionContext: transitionContext)
|
|
break
|
|
case .hidden?:
|
|
animateTransitionHiddenType(transitionContext: transitionContext)
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
// show
|
|
func animateTransitionShowType(transitionContext: UIViewControllerContextTransitioning) {
|
|
let fromController: UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
|
|
let toController: UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
|
|
let containerView = transitionContext.containerView
|
|
let width:CGFloat = (UIApplication.shared.keyWindow?.bounds.size.width)! * config.sideRelative
|
|
let x:CGFloat! = config.direction == .left ? 0.0 : ((UIApplication.shared.keyWindow?.bounds.size.width)! - width)
|
|
toController.view.frame = CGRect.init(x: x, y: 0, width: width, height: containerView.frame.height)
|
|
toController.view.clipsToBounds = true
|
|
// fromController UINavigationController
|
|
// toController SnapKitViewController
|
|
containerView.addSubview(toController.view)
|
|
containerView.addSubview(fromController.view)
|
|
|
|
var mask:GYSideMaskView?
|
|
for view in toController.view.subviews where view is GYSideMaskView {
|
|
mask = view as? GYSideMaskView
|
|
}
|
|
if mask == nil {
|
|
mask = GYSideMaskView()
|
|
fromController.view.addSubview(mask!)
|
|
}
|
|
mask?.frame = fromController.view.bounds
|
|
mask?.alpha = 0.0
|
|
mask?.isUserInteractionEnabled = false
|
|
|
|
let flag: CGFloat! = config.direction == .left ? -1.0 : 1.0
|
|
|
|
var fromTransform: CGAffineTransform = CGAffineTransform(translationX: -flag * width, y: 0)
|
|
let toTransform: CGAffineTransform = CGAffineTransform(translationX: flag * width, y: 0)
|
|
|
|
if self.config.animationType == .translationMask {
|
|
fromTransform = CGAffineTransform(translationX: 0, y: 0)
|
|
containerView.bringSubviewToFront(toController.view)
|
|
}else if self.config.animationType == .zoom {
|
|
let t1: CGAffineTransform = CGAffineTransform(translationX: -flag * width * config.zoomOffsetRelative, y: 0)
|
|
let t2: CGAffineTransform = CGAffineTransform(scaleX: config.zoomRelative, y: config.zoomRelative)
|
|
fromTransform = t1.concatenating(t2)
|
|
}
|
|
if self.config.animationType != .zoom {
|
|
toController.view.transform = toTransform
|
|
toController.view.frame = CGRect(x: toTransform.tx+x, y: 0, width: width, height: containerView.frame.height)
|
|
}else {
|
|
toController.view.transform = CGAffineTransform(translationX: 0, y: 0)
|
|
toController.view.frame = CGRect(x: 0, y: 0, width: width, height: containerView.frame.height)
|
|
}
|
|
|
|
UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: {
|
|
mask?.alpha = self.config.maskAlpha
|
|
toController.view.transform = .identity
|
|
fromController.view.transform = fromTransform
|
|
}) { (finished) in
|
|
if !transitionContext.transitionWasCancelled {
|
|
mask?.isUserInteractionEnabled = true
|
|
transitionContext.completeTransition(true)
|
|
containerView.addSubview(fromController.view)
|
|
if self.config.animationType == .translationMask {
|
|
containerView.bringSubviewToFront(toController.view)
|
|
}
|
|
}else {
|
|
mask?.destroy()
|
|
toController.view.transform = toTransform;
|
|
fromController.view.frame = containerView.frame;
|
|
transitionContext.completeTransition(false)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// hidde
|
|
func animateTransitionHiddenType(transitionContext: UIViewControllerContextTransitioning) {
|
|
let fromController:UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
|
|
let toController:UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
|
|
|
|
let containerView = transitionContext.containerView
|
|
let width:CGFloat = (UIApplication.shared.keyWindow?.bounds.size.width)! * self.config.sideRelative
|
|
let x:CGFloat! = config.direction == .left ? 0.0 : ((UIApplication.shared.keyWindow?.bounds.size.width)! - width)
|
|
|
|
fromController.view.frame = CGRect.init(x: x, y: 0, width: width, height: containerView.frame.height)
|
|
|
|
var mask:GYSideMaskView?
|
|
for view in toController.view.subviews {
|
|
if view.isKind(of: GYSideMaskView.classForCoder()){
|
|
mask = view as? GYSideMaskView
|
|
break
|
|
}
|
|
}
|
|
|
|
let flag: CGFloat! = config.direction == GYSideDirection.left ? -1.0 : 1.0
|
|
var fromTransform:CGAffineTransform = CGAffineTransform.init(translationX: flag * width, y: 0)
|
|
|
|
if self.config.animationType == .translationMask {
|
|
fromTransform = CGAffineTransform.init(translationX: flag * width, y: 0)
|
|
}else if self.config.animationType == .zoom {
|
|
fromTransform = CGAffineTransform.init(translationX: 0, y: 0)
|
|
containerView.bringSubviewToFront(toController.view)
|
|
}
|
|
|
|
UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: {
|
|
mask?.alpha = 0.001
|
|
fromController.view.transform = fromTransform
|
|
toController.view.transform = .identity
|
|
}) { (finished) in
|
|
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
|
|
if !transitionContext.transitionWasCancelled {
|
|
mask?.destroy()
|
|
}else {
|
|
if self.config.animationType != .zoom {
|
|
containerView.bringSubviewToFront(fromController.view)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
// print( NSStringFromClass(self.classForCoder) + " 销毁了---->4")
|
|
}
|
|
}
|
|
|