Swift ViewController幻灯片动画

Swift ViewController幻灯片动画,swift,facebook,animation,uiviewcontroller,tabbar,Swift,Facebook,Animation,Uiviewcontroller,Tabbar,我想在tabswitch上创建一个类似iOS应用程序facebook的动画。我已经尝试过开发某种动画,出现的问题是旧的视图控制器直接在开关上变为不可见,而不是在新控制器快速滑入时缓慢淡出 我发现这个问题很严重,但正确的标记解决方案对我来说并不适用(它不是幻灯片,而是渐变)。我还想得到的是使幻灯片向左或向右切换选项卡的功能。就像是在老版本的facebook上 到目前为止,我得到的是: extension TabBarController: UITabBarControllerDelegate {

我想在tabswitch上创建一个类似iOS应用程序facebook的动画。我已经尝试过开发某种动画,出现的问题是旧的视图控制器直接在开关上变为不可见,而不是在新控制器快速滑入时缓慢淡出

我发现这个问题很严重,但正确的标记解决方案对我来说并不适用(它不是幻灯片,而是渐变)。我还想得到的是使幻灯片向左或向右切换选项卡的功能。就像是在老版本的facebook上

到目前为止,我得到的是:

extension TabBarController: UITabBarControllerDelegate  {
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        guard let fromView = selectedViewController?.view,
              let toView = viewController.view else { return false }
        if fromView != toView {
            toView.transform = CGAffineTransform(translationX: -90, y: 0)
            UIView.animate(withDuration: 0.25, delay: 0.0, options: .curveEaseInOut, animations: {
                toView.transform = CGAffineTransform(translationX: 0, y: 0)
            })
        }; return true
    }
}

如何解决此问题?


[1]
我非常想从Facebook应用程序中添加gif。问题是我不想审查视频,只想透露太多我的数据。(即使fb已经拥有它们)。在youtube上我也没有找到合适的录音。请在iOS中的fb应用程序中亲自试用。

您可以使用以下想法:

此外,这是更新到Swift 4.1的代码,我还删除了原力展开:

import UIKit

class MyTabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        delegate = self
    }
}

extension MyTabBarController: UITabBarControllerDelegate  {
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        guard let tabViewControllers = tabBarController.viewControllers, let toIndex = tabViewControllers.index(of: viewController) else {
            return false
        }
        animateToTab(toIndex: toIndex)
        return true
    }

    func animateToTab(toIndex: Int) {
        guard let tabViewControllers = viewControllers,
            let selectedVC = selectedViewController else { return }

        guard let fromView = selectedVC.view,
            let toView = tabViewControllers[toIndex].view,
            let fromIndex = tabViewControllers.index(of: selectedVC),
            fromIndex != toIndex else { return }


        // Add the toView to the tab bar view
        fromView.superview?.addSubview(toView)

        // Position toView off screen (to the left/right of fromView)
        let screenWidth = UIScreen.main.bounds.size.width
        let scrollRight = toIndex > fromIndex
        let offset = (scrollRight ? screenWidth : -screenWidth)
        toView.center = CGPoint(x: fromView.center.x + offset, y: toView.center.y)

        // Disable interaction during animation
        view.isUserInteractionEnabled = false

        UIView.animate(withDuration: 0.3,
                       delay: 0.0,
                       usingSpringWithDamping: 1,
                       initialSpringVelocity: 0,
                       options: .curveEaseOut,
                       animations: {
                        // Slide the views by -offset
                        fromView.center = CGPoint(x: fromView.center.x - offset, y: fromView.center.y)
                        toView.center = CGPoint(x: toView.center.x - offset, y: toView.center.y)

        }, completion: { finished in
            // Remove the old view from the tabbar view.
            fromView.removeFromSuperview()
            self.selectedIndex = toIndex
            self.view.isUserInteractionEnabled = true
        })
    }
}
因此,您需要子类UITabBarController,还需要编写动画部分,您可以调整动画选项(延迟、持续时间等)

我希望这有帮助,干杯


我从未见过Facebook,所以我不知道动画是什么。但是,当选项卡栏控制器更改其选项卡(子视图控制器)时,您可以使用Apple为视图控制器之间的过渡添加自定义动画的内置机制,以连贯且不受任何干扰的方式制作任意动画。这称为自定义过渡动画

苹果公司于2013年首次引入这一机制。以下是他们的视频链接:

我立即在我的应用程序中采用了这一点,我认为这会让它们看起来更时髦。下面是我喜欢的选项卡栏控制器自定义转换的演示:

真正酷的是,一旦你决定了你想要什么样的动画,让过渡变得交互式(即,用手势而不是点击按钮来驱动它)很容易:

现在,你可能会说:好吧,但这不是我想象中的动画。没问题!一旦掌握了自定义过渡架构的窍门,就可以轻松地将动画更改为任何您喜欢的内容。在这个变体中,我只是注释掉了一行,以便“旧”视图控制器不会滑开:


所以,让你的想象力尽情发挥吧!采用iOS想要的自定义过渡动画。

如果您想要pushViewController导航,您可以试试这个

但是,在TabBarController上的选项卡之间切换时,这将不起作用。为此,我会选择@mihai erős的解决方案

根据您的喜好更改动画持续时间,并将该类指定给幻灯片动画的导航序列

class CustomPushSegue: UIStoryboardSegue {

    override func perform() {
        // first get the source and destination view controllers as UIviews so that they can placed in navigation stack

        let sourceVCView = self.source.view as UIView!
        let destinationVCView = self.destination.view as UIView!
        let screenWidth = UIScreen.main.bounds.size.width

        //create the destination view's rectangular frame i.e starting at 0,0 and equal to screenwidth by screenheight
        destinationVCView?.transform = CGAffineTransform(translationX: screenWidth, y: 0)

        //the destinationview needs to be placed on top(aboveSubView) of source view in the app window stack before being accessed by nav stack
        // get the window and insert destination View
        let window = UIApplication.shared.keyWindow
        window?.insertSubview(destinationVCView!, aboveSubview: sourceVCView!)


        // the animation: first remove the source out of screen by moving it at the left side of it and at the same time place the destination to source's position
        // Animate the transition.
        UIView.animate(withDuration: 0.3, animations: { () -> Void in
            sourceVCView?.transform = CGAffineTransform(translationX: -screenWidth,y: 0)
            destinationVCView?.transform = CGAffineTransform.identity

        }, completion: { (Finished) -> Void in
            self.source.present(self.destination, animated: false, completion: nil)
        }) 
    }
}

那个么为什么你们提到的答案不适合你们呢?这里有一个使用
UIViewControllerAnimatedTransitioning
的要点:你们也可以发布一些代码吗?我真的很想看看您是如何实现这个自定义转换的。有关生成这些转换的代码,请参阅@matt,非常感谢您!谢谢@matt的回答和WWDC的视频链接当然,好了。哦,是的,我在读别的东西。从我的观点来看,我不知道这是否是一个好的UI/UX,你是从Facebook应用程序的一个功能开始的,幻灯片手势在Facebook应用程序中不存在。你应该发布一个新的问题,你要求的动画…当过渡发生时,控制器的顶栏颜色改变,它会导致恼人的闪光效果。如何解决?请检查视频@UtkuDalmaz您能在github或其他地方发布您的代码示例吗?如果我可以复制的话,我可以调查你的问题。我已经发布了我的代码。我用的是你的代码,但后来我改成了类似的代码,你能帮我吗?
class CustomPushSegue: UIStoryboardSegue {

    override func perform() {
        // first get the source and destination view controllers as UIviews so that they can placed in navigation stack

        let sourceVCView = self.source.view as UIView!
        let destinationVCView = self.destination.view as UIView!
        let screenWidth = UIScreen.main.bounds.size.width

        //create the destination view's rectangular frame i.e starting at 0,0 and equal to screenwidth by screenheight
        destinationVCView?.transform = CGAffineTransform(translationX: screenWidth, y: 0)

        //the destinationview needs to be placed on top(aboveSubView) of source view in the app window stack before being accessed by nav stack
        // get the window and insert destination View
        let window = UIApplication.shared.keyWindow
        window?.insertSubview(destinationVCView!, aboveSubview: sourceVCView!)


        // the animation: first remove the source out of screen by moving it at the left side of it and at the same time place the destination to source's position
        // Animate the transition.
        UIView.animate(withDuration: 0.3, animations: { () -> Void in
            sourceVCView?.transform = CGAffineTransform(translationX: -screenWidth,y: 0)
            destinationVCView?.transform = CGAffineTransform.identity

        }, completion: { (Finished) -> Void in
            self.source.present(self.destination, animated: false, completion: nil)
        }) 
    }
}