当前位置: 首页 > 面试题库 >

如何使用CrossDissolve幻灯片过渡为Tab栏选项卡开关设置动画?

郭均
2023-03-14
问题内容

我试图在UITabBarController某种类似于Facebook应用程序的效果上创建过渡效果。我设法在选项卡开关上获得了“滚动效果”,但是我似乎无法弄清楚如何交叉溶解(或者至少不起作用)。

这是我当前的代码:

import UIKit

class ScrollingTabBarControllerDelegate: NSObject, UITabBarControllerDelegate {
    func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {

        return ScrollingTransitionAnimator(tabBarController: tabBarController, lastIndex: tabBarController.selectedIndex)
    }
}

class ScrollingTransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {
    weak var transitionContext: UIViewControllerContextTransitioning?
    var tabBarController: UITabBarController!
    var lastIndex = 0

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.2
    }

    init(tabBarController: UITabBarController, lastIndex: Int) {
        self.tabBarController = tabBarController
        self.lastIndex = lastIndex
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        self.transitionContext = transitionContext

        let containerView = transitionContext.containerView
        let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
        let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)

        containerView.addSubview(toViewController!.view)

        var viewWidth = toViewController!.view.bounds.width

        if tabBarController.selectedIndex < lastIndex {
            viewWidth = -viewWidth
        }

        toViewController!.view.transform = CGAffineTransform(translationX: viewWidth, y: 0)

        UIView.animate(withDuration: self.transitionDuration(using: (self.transitionContext)), delay: 0.0, usingSpringWithDamping: 1.2, initialSpringVelocity: 2.5, options: .transitionCrossDissolve, animations: {
            toViewController!.view.transform = CGAffineTransform.identity
            fromViewController!.view.transform = CGAffineTransform(translationX: -viewWidth, y: 0)
        }, completion: { _ in
            self.transitionContext?.completeTransition(!self.transitionContext!.transitionWasCancelled)
            fromViewController!.view.transform = CGAffineTransform.identity
        })
    }
}

如果有人知道如何使它正常工作,已经尝试了好几天却没有任何进展,那就太好了…:/

编辑: 我通过将UIView.animate块替换为来实现交叉分解工作:

UIView.transition(with: containerView, duration: 0.2, options: .transitionCrossDissolve, animations: {

    toViewController!.view.transform = CGAffineTransform.identity
    fromViewController!.view.transform = CGAffineTransform(translationX: -viewWidth, y: 0)

}, completion: { _ in

    self.transitionContext?.completeTransition(!self.transitionContext!.transitionWasCancelled)
    fromViewController!.view.transform = CGAffineTransform.identity

})

但是 ,该动画确实很慢并且不可用:(

编辑2: 对于尝试使用这些摘要的人们,请不要忘记为挂接代表UITabBarController,否则将不会发生任何事情。

编辑3: 我发现了一个Swift库,它确实可以满足我的需求:https : //github.com/Interactive-
Studio/TransitionableTab


问题答案:

有一种更简单的方法可以做到这一点。在标签栏委托中添加以下代码:

在Swift 2、3和4上工作

class MySubclassedTabBarController: UITabBarController {

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

extension MySubclassedTabBarController: UITabBarControllerDelegate  {
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {

        guard let fromView = selectedViewController?.view, let toView = viewController.view else {
          return false // Make sure you want this as false
        }

        if fromView != toView {
          UIView.transition(from: fromView, to: toView, duration: 0.3, options: [.transitionCrossDissolve], completion: nil)
        }

        return true
    }
}

编辑(4/23/18) 由于此答案越来越流行,因此我更新了代码以删除强制展开,这是一个不好的做法,并添加了保护声明。

编辑(18/11/11) @AlbertoGarcía是正确的。如果您两次点击标签栏图标,则会出现空白屏幕。所以我加了一张额外的支票



 类似资料:
  • 我目前正在开发一个使用jQuery Mobile的移动网站。切换页面时,我使用幻灯片过渡。因为这些页面很长,需要滚动。 向下滚动并单击链接时,当页面在滑入新页面之前滚动到顶部时,会出现可见的跳转。由于在某些时候需要滚动到顶部时,这两个页面并排放置。 我尝试过的一件事是:我可以将新页面从顶部偏移,使其从页面滚动到的级别开始,并在动画完成时将偏移重置回0,但之后页面将保持向下滚动。如果我使用窗口。sc

  • 上下文:C#中的PowerPoint幻灯片有一个属性slide。名称(通常包含任意字符串值)。在我的C#应用程序中,我想使用这个属性来标识幻灯片(幻灯片顺序不可靠)。 问题:如何手动设置幻灯片。PowerPoint应用程序中的Name属性? 我的问题非常像:“如何在PowerPoint幻灯片中命名对象?”,但只是在幻灯片级别上。 任何帮助都将不胜感激。

  • 我使用jQuery slick插件(http://kenwheeler.github.io/slick/)创建了一个轮播。我想使用“幻灯片”设置来指定旋转木马中使用哪些元素。此设置的说明为: 类型:元素 默认值:“” 用作幻灯片的元素查询 我对这个设置的理解是,如果我指定了'div',那么只有div元素将显示在轮播中。我不能让它运转起来。当我创建轮播时,容器中的所有元素都会显示出来。 我创建了一个

  • 本文向大家介绍如何使用C#操作幻灯片,包括了如何使用C#操作幻灯片的使用技巧和注意事项,需要的朋友参考一下 记得老师讲课的时候,经常会用PPT遥控翻页笔来遥控幻灯片来给我们讲课,当时觉得非常有趣,由于这段时间接触了VSTO相关的开发,了解到了Office的相关产品都公开了一些API来让我们对Office产品进行二次开发,这时候我就想,能不能用PowerPoint公开的对象来制作一个遥控幻灯片的程序

  • 我想拿一张PowerPoint幻灯片(“源”),并将其插入到另一张已经包含一些内容的PowerPoint幻灯片(“目标”)中,位于源PowerPoint幻灯片中的特定位置。 我已经尝试了几种方法来研究这样做的代码,但是我不断得到将幻灯片合并到PowerPoint演示文稿中的结果,这不是我想要的。我想拿一张现有的幻灯片并将其插入到另一张幻灯片中,就像在现有幻灯片中插入图片一样。 我有另一位同事编写的

  • 使用幻灯片组件,你需要在 sm.js 和 sm.css 之后额外引入如下两个文件: <link rel="stylesheet" href="//g.alicdn.com/msui/sm/0.6.2/css/sm-extend.min.css"> <script type='text/javascript' src='//g.alicdn.com/msui/sm/0.6.2/js/sm-exte