ViewController幻灯片动画

时间:2018-07-23 15:40:55

标签: swift facebook animation uiviewcontroller tabbar

我想在tabswitch [1] 上创建类似于 iOS app facebook的动画。我已经尝试开发某种动画,出现的问题是旧的视图控制器直接在开关上变得不可见,而不是在新控制器快速滑动时逐渐消失。

我已经找到了这样的问题How to animate Tab bar tab switch with a CrossDissolve slide transition?,但是标记为正确的解决方案对我而言实际上并不起作用(这不是幻灯片,而是淡入淡出的过渡)。我还想获得的功能是向左或向右滑动以切换选项卡。就像在旧版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
    }
}

class TabBarController: UITabBarController {
    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }
}

如何解决此问题?


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

3 个答案:

答案 0 :(得分:7)

我从没看过Facebook,所以我不知道动画是什么。但是,当标签栏控制器使用Apple内置的机制连贯地并且没有任何黑客攻击时,当标签栏控制器更改其标签(子视图控制器)时,您可以拥有任何任何动画。提供了向视图控制器之间的过渡添加自定义动画的功能。这就是自定义过渡动画

Apple于2013年首次引入了这种机制。这是他们有关此视频的链接:https://developer.apple.com/videos/play/wwdc2013/218/

我立即在我的应用程序中采用了此功能,我认为这使它们看起来更加漂亮。这是我喜欢的标签栏控制器自定义过渡的演示:

enter image description here

真正很酷的事情是,一旦您确定了想要的动画,进行过渡 interactive (即用手势而不是单击按钮来驱动它)就很容易了:

enter image description here

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

enter image description here

因此,让您的想象力疯狂起来!采用自定义过渡动画,这正是iOS的意图。

答案 1 :(得分:5)

您可以使用以下想法:https://samwize.com/2016/04/27/making-tab-bar-slide-when-selected/

此外,这是更新到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的子类,并且还必须编写动画部分,您可以调整动画选项(延迟,持续时间等)。

我希望它会有所帮助,加油!

enter image description here

答案 2 :(得分:2)

如果您需要用于pushViewController导航的内容,可以尝试一下。

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

根据您的喜好更改动画的持续时间,并将此类别分配给导航动画,以进行幻灯片动画。

$ bin/kafka-server-start.sh -daemon config/kafka-server.properties 
$ echo $!
$ ps aux |grep kafka-server |grep -v grep
$