适用于hidesBottomBarWhenPushed的iOS自定义动画

Mic*_*ine 6 uitabbarcontroller uiviewcontroller uinavigationcontroller ios swift

我的应用程序的结构是TabBarController-> NavigationController-> FirstViewController-> SecondViewController。我使用从FirstViewController到SecondViewController的自定义推送过渡来模仿循环过渡。我不想在SecondViewController上显示底部的TabBar。因此,我在SecondViewController上设置了“ hidesBottomBarWhenPushed = true”。

问题在于,当发生圆形动画时,默认情况下底部的tabBar会向左滑动。我想自定义该动画以执行其他操作(可能溶解或执行某些操作)。

这可能吗?

ps我会尝试通过设置'isHidden = true'或'alpha = 0'来避免仅隐藏底部的TabBar,因为这会增加一些小麻烦。

Onn*_*ijk 1

我今天遇到了这个问题,并成功地使 TabBar 向下滑动而不是向左滑动。至少可以在 iOS 13 上运行。

我使用动画制作器进行过渡,以额外为 TabBar 制作动画并抵消默认动画。

class CustomTransition: NSObject, UIViewControllerAnimatedTransitioning {
    static let duration: TimeInterval = 0.5

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        Self.duration
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let from = transitionContext.viewController(forKey: .from)!
        let to = transitionContext.viewController(forKey: .to)!

        let animator = UIViewPropertyAnimator(duration: Self.duration, curve: .easeInOut)

        // Configure animator for transition like normal.
        // ...

        // Now handle the TabBar.
        if
            to.hidesBottomBarWhenPushed,
            !from.hidesBottomBarWhenPushed,
            let tabBar = from.tabBarController?.tabBar
        {
            // TabBar is going away.

            animator.addAnimations {
                // Counteract default animation by animating x in opposite direction.
                tabBar.center.x += tabBar.bounds.width

                // Animate TabBar down.
                tabBar.center.y += tabBar.bounds.height

                // Or alternatively animate opacity.
                // tabBar.alpha = 0
            }
        }
        else if
            !to.hidesBottomBarWhenPushed,
            from.hidesBottomBarWhenPushed,
            let tabBar = to.tabBarController?.tabBar
        {
            // TabBar is coming back.

            // TabBar by default will be animated toward default position.
            // Make sure it's already there on x so default animation does nothing for x.
            tabBar.center.x = tabBar.bounds.width / 2

            // Move y down, so default animation will move TabBar up to default position.
            tabBar.center.y += tabBar.bounds.height

            // Or alternatively animate opacity.
            // tabBar.alpha = 0
            // animator.addAnimations {
            //    tabBar.alpha = 1
            //}
        }

        animator.startAnimation()
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:
上述解决方案似乎不适用于横向。我选择了以下解决方案,但它变得越来越黑客。不知何故,您只能在启动自己的动画后从 TabBar 层中删除默认动画,就像那些相关的那样。

我已经在不同方向的各种设备上对此进行了测试,它似乎工作一致,至少在 iOS 13 上是这样。

// Start transition animation.
animator.startAnimation()

if let tabBar = pushedController.tabBarController?.tabBar {
    // Remove default TabBar animation.
    tabBar.layer.removeAllAnimations()
    if pushedController == to {
        // Move TabBar back to its place.
        tabBar.center.x = tabBar.bounds.width / 2

        // Now animate it out again.
        animator.addAnimations {
            tabBar.center.y += tabBar.bounds.height
        }
    } else {
        // Move TabBar down out of view.
        tabBar.center.y += tabBar.bounds.height

        // Now animate it in.
        animator.addAnimations {
            tabBar.center.y -= tabBar.bounds.height
        }
    }
}
Run Code Online (Sandbox Code Playgroud)