交互动画的优先级比 不交互动画高
//交互动画 主要是手势动画
func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return PanInteraction(detailView: ViewController())
}
func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return nil
}
class PanInteraction: UIPercentDrivenInteractiveTransition {
let detailVC: UIViewController
init(detailView: ViewController) {
self.detailVC = detailView
super.init()
let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePan(pan:)))
detailView.view.addGestureRecognizer(pan)
}
@objc func handlePan(pan: UIPanGestureRecognizer ){
let progress = pan.translation(in: pan.view).x / UIScreen.main.bounds.width
switch pan.state {
case .began:
detailVC.dismiss(animated: true, completion: nil)
case .changed:
update(progress)
case .cancelled,.ended:
if progress > 0.5 {
finish()
}else{
cancel()
}
default: break
}
}
}
UINavigation 自定义动画
extension MainViewController: UINavigationControllerDelegate {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let _ = segue.destination as? ViewController {
panInteraction = PanAnimation(detailVC: ViewController())
}
}
func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?{
guard let panInteraction = panInteraction else {
return nil
}
return panInteraction
}
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?{
switch operation {
case .push:
return PushAnimator()
case .pop:
return PopAnimator()
default:
return nil
}
}
}
class PushAnimator: NSObject,UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.3
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
guard let fromVC = transitionContext.viewController(forKey: .from),
let toVC = transitionContext.viewController(forKey: .to),
let fromView = transitionContext.view(forKey: .from),
let toView = transitionContext.view(forKey: .to) else{ return }
containerView.addSubview(toView)
toView.transform = CGAffineTransform(translationX: containerView.frame.width, y: 0)
UIView.animate(
withDuration: transitionDuration(using: transitionContext),
animations: {
fromView.transform = CGAffineTransform(translationX: -containerView.frame.width, y: 0)
fromView.alpha = 0
toView.alpha = 1
toView.transform = .identity
}) { _ in
fromView.transform = .identity
toView.transform = .identity
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
}
class PopAnimator: NSObject,UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.3
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
guard let fromVC = transitionContext.viewController(forKey: .from),
let toVC = transitionContext.viewController(forKey: .to),
let fromView = transitionContext.view(forKey: .from),
let toView = transitionContext.view(forKey: .to) else{ return }
containerView.insertSubview(toView, belowSubview: fromView)
//和shadowPath一样 视图虽然被移除了 但是 属性仍在 所以直接设为原来状态
toView.alpha = 1
toView.transform = CGAffineTransform(translationX: -containerView.frame.width/3, y: 0)
//除shadowOpacity都有默认值 实现简单阴影只要给shadowOpacity就可以
fromView.layer.shadowOpacity = 0.5
fromView.layer.shadowRadius = 10
//若指定shadowPath 系统会自动帮我们找到对应的view 渲染阴影
fromView.layer.shadowPath = UIBezierPath(rect: fromView.bounds).cgPath
UIView.animate(
withDuration: transitionDuration(using: transitionContext),
animations: {
fromView.transform = CGAffineTransform(translationX: containerView.frame.width, y: 0)
toView.transform = .identity
}) { _ in
fromView.transform = .identity
toView.transform = .identity
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
}
Tabbar自定义动画
import UIKit
enum Operation {
case toRight,toLeft
}
class TabBarViewController: UITabBarController {
var customInteraction: CustomInteraction!
override func viewDidLoad() {
super.viewDidLoad()
customInteraction = CustomInteraction(tabBarVC: self)
self.delegate = self
}
}
extension TabBarViewController: UITabBarControllerDelegate {
//非交互动画
func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let fromIndex = tabBarController.viewControllers!.firstIndex(of: fromVC)!
let toIndex = tabBarController.viewControllers!.firstIndex(of: toVC)!
let operation: Operation = toIndex > fromIndex ? .toRight : .toLeft
return CustomAnimator(operation: operation)
}
//交互动画
func tabBarController(_ tabBarController: UITabBarController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return customInteraction.isInteractive ? customInteraction : nil
}
}
非交互动画
import UIKit
class CustomAnimator: NSObject,UIViewControllerAnimatedTransitioning {
let operation: Operation
init(operation: Operation) {
self.operation = operation
super.init()
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.3
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
guard let fromView = transitionContext.view(forKey: .from),
let toView = transitionContext.view(forKey: .to) else {
return
}
containerView.addSubview(toView)
let offset = containerView.frame.width
toView.frame.origin.x = (operation == .toRight) ? offset : -offset
toView.alpha = 0
UIView.animate(
withDuration: transitionDuration(using: transitionContext),
animations: {
fromView.alpha = 0
let offset = containerView.frame.width
fromView.frame.origin.x = (self.operation == .toRight) ? -offset : offset
toView.alpha = 1
toView.frame.origin.x = 0
}) { _ in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
}
交互动画
import UIKit
class CustomInteraction: UIPercentDrivenInteractiveTransition {
var isInteractive = false
let tabBarVC: TabBarViewController
init(tabBarVC: TabBarViewController) {
self.tabBarVC = tabBarVC
super.init()
let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePan(pan:)))
tabBarVC.view.addGestureRecognizer(pan)
}
@objc func handlePan(pan: UIPanGestureRecognizer){
let translationX = pan.translation(in: pan.view).x
let progress = abs(translationX / 200)
switch pan.state {
case .began:
isInteractive = true
//translationX 小于0 是用户向左滑 大于0 是向右滑
if translationX < 0 {
if tabBarVC.selectedIndex <= tabBarVC.viewControllers!.count - 2 {
tabBarVC.selectedIndex += 1
}
}else{
if tabBarVC.selectedIndex >= 1 {
tabBarVC.selectedIndex -= 1
}
}
case .changed:
update(progress)
case .cancelled,.ended:
isInteractive = false
if progress > 0.5 {
finish()
}else{
cancel()
}
default:
break
}
}
}
网友评论