Wallpaper_Home/wallpaper_project/Pods/GYSide/Classes/GYSideAnimatedTransitioning.swift
2024-04-17 14:37:20 +08:00

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