标签栏点击前ViewDisappear动画

ViewDisappear animation before tabbar click

我有一个 TabBarController,它有 3 个 navigationController,每个都有对应的 viewController:AViewController、BViewController 和 CViewController。第一个有一个 UIView 元素,我想在 viewDisappears 使用时针对它 运行 动画:

UIView.animateWithDuration(duration, delay: 0.0, options: .CurveEaseOut, animations: {

期间...

override func viewWillDisappear(animated: Bool) {

如果用户点击标签栏中的第 2 项或第 3 项,我希望该动画首先发生,然后将用户带到第 2 项或第 3 项。

问题是,当用户单击不同的项目时,TabBarController 中的这段代码在我的 ViewController A

中的 viewwillDisappears 之前首先被触发
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {

然后我的动画没有 ​​运行。

我应该将动画放在哪里,以便在 运行 秒之前将用户带到标签栏中的其他项目?

您可以从 UITabBarControllerDelegate、return false 实现 tabBarController:shouldSelectViewController:,播放您的动画,然后以编程方式更改选项卡。

您需要编写自己的 UIViewControllerAnimatedTransitioning (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewControllerAnimatedTransitioning_Protocol/)

试试这个代码:

TabBarController.swift

import UIKit
class TabBarController: UITabBarController, UITabBarControllerDelegate {

var buttons = [UIButton]()

override func viewDidLoad() {
    super.viewDidLoad()
    self.delegate = self

    var newViewControllers = [UIViewController]()

    for index in 0..<2 {
        let viewController = ViewController()
        var tabBarItem = UITabBarItem()

        switch index {
        case 0:
            viewController.view.backgroundColor = UIColor.blueColor()
            viewController.label.textColor = UIColor.whiteColor()
            tabBarItem = UITabBarItem(tabBarSystemItem: .More, tag: index)
        case 1:
            viewController.view.backgroundColor = UIColor.greenColor()
            viewController.label.textColor = UIColor.blackColor()
            tabBarItem = UITabBarItem(tabBarSystemItem: .Favorites, tag: index)
        default:
            break
        }

        viewController.label.text = "Text \(index)"
        viewController.tabBarItem = tabBarItem
        newViewControllers.append(viewController)
        //tabBar.items![index] = tabBarItem

    }

    selectedIndex = 0
   //    = newViewControllers
    setViewControllers(newViewControllers, animated: false)
    // Do any additional setup after loading the view, typically from a nib.
}

func tabBarController(tabBarController: UITabBarController, animationControllerForTransitionFromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    let fromIndex = tabBarController.viewControllers!.indexOf(fromVC)!
    let toIndex = tabBarController.viewControllers!.indexOf(toVC)!

    let tabChangeDirection: TabOperationDirection = toIndex < fromIndex ? .Left : .Right
    let transitionType = SDETransitionType.TabTransition(tabChangeDirection)
    let slideAnimationController = SlideAnimationController(type: transitionType)
    return slideAnimationController

}
}

ViewController.swift

import UIKit
class ViewController: UIViewController {

let label = UILabel(frame: CGRect(x: 40, y: 60, width: 80, height: 40))

override func viewDidLoad() {
    super.viewDidLoad()
    view.addSubview(label)
}

var labelHidden = false {
    willSet(value) {
        if value {
            self.label.frame.origin.y = -40
        } else {
            self.label.frame.origin.y = 60
        }
    }
}
}

SlideAnimationController.swift (resource: https://github.com/seedante/iOS-ViewController-Transition-Demo)

import UIKit

enum SDETransitionType{
case NavigationTransition(UINavigationControllerOperation)
case TabTransition(TabOperationDirection)
case ModalTransition(ModalOperation)
}

enum TabOperationDirection{
case Left, Right
}

enum ModalOperation{
case Presentation, Dismissal
}

class SlideAnimationController: NSObject, UIViewControllerAnimatedTransitioning {

private var transitionType: SDETransitionType

init(type: SDETransitionType) {
    transitionType = type
    super.init()
}

func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
    return 0.3
}

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

    guard let containerView = transitionContext.containerView(), fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey), toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) else{
        return
    }

    let fromView = fromVC.view
    let toView = toVC.view

    var translation = containerView.frame.width
    var toViewTransform = CGAffineTransformIdentity
    var fromViewTransform = CGAffineTransformIdentity

    switch transitionType{
    case .NavigationTransition(let operation):
        translation = operation == .Push ? translation : -translation
        toViewTransform = CGAffineTransformMakeTranslation(translation, 0)
        fromViewTransform = CGAffineTransformMakeTranslation(-translation, 0)
    case .TabTransition(let direction):
        translation = direction == .Left ? translation : -translation
        fromViewTransform = CGAffineTransformMakeTranslation(translation, 0)
        toViewTransform = CGAffineTransformMakeTranslation(-translation, 0)
    case .ModalTransition(let operation):
        translation =  containerView.frame.height
        toViewTransform = CGAffineTransformMakeTranslation(0, (operation == .Presentation ? translation : 0))
        fromViewTransform = CGAffineTransformMakeTranslation(0, (operation == .Presentation ? 0 : translation))
    }

    switch transitionType{
    case .ModalTransition(let operation):
        switch operation{
        case .Presentation: containerView.addSubview(toView)
        case .Dismissal: break
        }
    default: containerView.addSubview(toView)
    }

    toView.transform = toViewTransform

    if let fromVC = fromVC as? ViewController {
        UIView.animateWithDuration(0.3, delay: 0.0, options: .CurveEaseOut, animations: {
            fromVC.labelHidden = true
            }, completion: {
                bool in
                UIView.animateWithDuration(self.transitionDuration(transitionContext), animations: {
                    fromView.transform = fromViewTransform
                    toView.transform = CGAffineTransformIdentity
                    }, completion: { finished in
                        fromView.transform = CGAffineTransformIdentity
                        toView.transform = CGAffineTransformIdentity

                        let isCancelled = transitionContext.transitionWasCancelled()
                        transitionContext.completeTransition(!isCancelled)

                        fromVC.labelHidden = false
                })
        })
    }
}
}