返回

iOS 仿小红书 push pop 转场动画,打造惊艳交互体验

Android

iOS 转场动画进阶:仿小红书惊艳的 push 和 pop 交互

前言

随着 iOS 7 的推出,苹果赋予开发者自定义转场动画的强大功能,开辟了打造交互体验新高度的可能性。本文将深入探索如何仿照小红书的标志性 push 和 pop 转场动画,为您的 iOS 应用程序增添一抹惊艳的色彩。

小红书 push 转场动画解析

小红书 push 转场动画由两个关键动作组成:

  • 新页面从右向左平移进入屏幕
  • 旧页面同时从左向右平移退出屏幕

仿小红书 push 转场动画实现

  1. 创建 UIViewControllerAnimatedTransitioning 子类: 定义自定义转场动画的行为。

  2. 实现 animateTransition 方法: 在此方法中,利用 UIViewPropertyAnimator 执行平移动画。

  3. 配置动画参数: 调整持续时间、延迟和阻尼,优化动画效果。

class PushTransition: UIViewControllerAnimatedTransitioning {
    // 设置转场持续时间
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.3
    }

    // 执行转场动画
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        // 获取新旧页面视图控制器
        guard let toViewController = transitionContext.viewController(forKey: .to),
              let fromViewController = transitionContext.viewController(forKey: .from) else {
            return
        }

        // 获取动画容器视图
        let containerView = transitionContext.containerView

        // 添加新页面视图到容器视图
        containerView.addSubview(toViewController.view)

        // 设置新旧页面视图的初始位置
        toViewController.view.frame = CGRect(x: containerView.bounds.width, y: 0, width: containerView.bounds.width, height: containerView.bounds.height)
        fromViewController.view.frame = CGRect(x: 0, y: 0, width: containerView.bounds.width, height: containerView.bounds.height)

        // 创建平移动画属性对象
        let animator = UIViewPropertyAnimator(duration: 0.3, curve: .easeIn) {
            // 新页面平移到屏幕中央
            toViewController.view.frame = CGRect(x: 0, y: 0, width: containerView.bounds.width, height: containerView.bounds.height)

            // 旧页面平移出屏幕
            fromViewController.view.frame = CGRect(x: -containerView.bounds.width, y: 0, width: containerView.bounds.width, height: containerView.bounds.height)
        }

        // 启动动画
        animator.startAnimation()

        // 动画完成后,完成转场
        animator.addCompletion { _ in
            // 移除旧页面视图
            fromViewController.view.removeFromSuperview()

            // 通知系统转场已完成
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        }
    }
}

小红书 pop 转场动画解析

与 push 动画相反,pop 转场动画呈现出以下动作:

  • 旧页面从右向左平移进入屏幕
  • 新页面同时从左向右平移退出屏幕

仿小红书 pop 转场动画实现

实现 pop 转场动画遵循与 push 动画类似的步骤,只不过平移动画的方向相反。

class PopTransition: UIViewControllerAnimatedTransitioning {
    // 设置转场持续时间
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.3
    }

    // 执行转场动画
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        // 获取新旧页面视图控制器
        guard let toViewController = transitionContext.viewController(forKey: .to),
              let fromViewController = transitionContext.viewController(forKey: .from) else {
            return
        }

        // 获取动画容器视图
        let containerView = transitionContext.containerView

        // 添加新页面视图到容器视图
        containerView.addSubview(toViewController.view)

        // 设置新旧页面视图的初始位置
        toViewController.view.frame = CGRect(x: -containerView.bounds.width, y: 0, width: containerView.bounds.width, height: containerView.bounds.height)
        fromViewController.view.frame = CGRect(x: 0, y: 0, width: containerView.bounds.width, height: containerView.bounds.height)

        // 创建平移动画属性对象
        let animator = UIViewPropertyAnimator(duration: 0.3, curve: .easeIn) {
            // 旧页面平移到屏幕中央
            toViewController.view.frame = CGRect(x: 0, y: 0, width: containerView.bounds.width, height: containerView.bounds.height)

            // 新页面平移出屏幕
            fromViewController.view.frame = CGRect(x: containerView.bounds.width, y: 0, width: containerView.bounds.width, height: containerView.bounds.height)
        }

        // 启动动画
        animator.startAnimation()

        // 动画完成后,完成转场
        animator.addCompletion { _ in
            // 移除新页面视图
            fromViewController.view.removeFromSuperview()

            // 通知系统转场已完成
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        }
    }
}

常见问题解答

1. 如何在代码中使用这些转场动画?

在 viewDidLoad 或 viewWillAppear 方法中,使用以下代码将自定义转场动画应用于导航控制器:

navigationController?.delegate = self

并在以下代理方法中使用自定义转场动画类:

func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    // 根据操作类型(push 或 pop)返回自定义转场动画类
}

2. 如何调整动画持续时间或阻尼?

您可以在创建 UIViewPropertyAnimator 对象时调整持续时间、延迟和阻尼参数。

3. 如何在动画过程中执行额外的动作?

您可以在 UIViewPropertyAnimator 的 addAnimations 或 addCompletion 块中执行额外的动作,例如更新约束或执行其他动画。

4. 如何禁用转场动画?

您可以在导航控制器代理方法中返回 nil 来禁用转场动画。

5. 如何处理转场取消?

您可以在 UIViewPropertyAnimator 的 addCompletion 块中处理转场取消的情况,例如还原任何更改或重置视图状态。

总结

通过自定义转场动画,您可以为您的 iOS 应用程序增添一抹优雅和吸引力。仿照小红书的 push 和 pop 动画,您可以打造惊艳的交互体验,让用户沉浸其中。本文提供的详细说明和代码示例将帮助您轻松地实现这些令人印象深刻的转场效果,提升您的应用程序的整体品质。