Skip to content

创建交互式转场(Interactive_Transitions)

创建交互式转场,让你的应用更具吸引力!🎉 交互式转场允许用户通过手势控制视图控制器之间的切换,提供更自然、更流畅的用户体验。准备好让你的应用动起来了吗?

交互式转场简介

交互式转场不仅仅是简单的动画,它允许用户在转场过程中进行干预。想象一下,用户可以通过滑动屏幕来控制视图控制器的显示进度,这种互动性大大提升了用户体验。交互式转场通常与手势识别器结合使用,例如 UIPanGestureRecognizer,来检测用户的手势并驱动转场动画。

  • 核心概念: 用户手势驱动动画。
  • 优势: 提升用户体验,增加应用的互动性。
  • 应用场景: 模态视图控制器的 dismiss,导航控制器的 push/pop。

实现交互式转场的步骤

要实现交互式转场,你需要遵循以下步骤:

  1. 创建手势识别器: 使用 UIPanGestureRecognizer 或其他手势识别器来检测用户的手势。
  2. 创建转场控制器: 实现 UIViewControllerInteractiveTransitioning 协议,负责管理转场动画的进度。
  3. 关联手势和转场: 在手势识别器的回调方法中,更新转场控制器的进度。
  4. 启动转场: 调用 startInteractiveTransition(_:) 方法启动转场。

代码示例:模态视图控制器的交互式 Dismiss

让我们通过一个例子来演示如何实现模态视图控制器的交互式 dismiss。首先,创建一个自定义的转场控制器:

swift
class InteractiveDismissalTransition: NSObject, UIViewControllerInteractiveTransitioning {
    var interactionInProgress = false
    private var viewController: UIViewController!
    private var completionReceiver: ((Bool) -> Void)?

    func startInteractiveTransition(_ transitionContext: UIViewControllerContextTransitioning) {
        // 保存视图控制器和完成回调
        viewController = transitionContext.viewController(forKey: .to)
        completionReceiver = { didComplete in
            transitionContext.completeTransition(didComplete)
        }
    }

    func updateInteractiveTransition(_ percentComplete: CGFloat) {
        // 更新转场进度
        viewController.view.transform = CGAffineTransform(translationX: 0, y: percentComplete * viewController.view.bounds.height)
    }

    func finishInteractiveTransition() {
        // 完成转场动画
        UIView.animate(withDuration: 0.3, animations: {
            self.viewController.view.transform = .identity
        }, completion: { _ in
            self.completionReceiver?(true)
        })
    }

    func cancelInteractiveTransition() {
        // 取消转场动画
        UIView.animate(withDuration: 0.3, animations: {
            self.viewController.view.transform = .identity
        }, completion: { _ in
            self.completionReceiver?(false)
        })
    }

    var wantsInteractiveStart: Bool {
        return interactionInProgress
    }
}

接下来,在模态视图控制器中添加手势识别器,并关联转场控制器:

swift
class ModalViewController: UIViewController {
    let interactiveTransition = InteractiveDismissalTransition()

    override func viewDidLoad() {
        super.viewDidLoad()

        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
        view.addGestureRecognizer(panGesture)
    }

    @objc func handlePanGesture(_ gesture: UIPanGestureRecognizer) {
        let translation = gesture.translation(in: view)
        let percent = translation.y / view.bounds.height

        switch gesture.state {
        case .began:
            interactiveTransition.interactionInProgress = true
            dismiss(animated: true, completion: nil)
        case .changed:
            interactiveTransition.updateInteractiveTransition(percent)
        case .cancelled:
            interactiveTransition.interactionInProgress = false
            interactiveTransition.cancelInteractiveTransition()
        case .ended:
            interactiveTransition.interactionInProgress = false
            if percent > 0.5 {
                interactiveTransition.finishInteractiveTransition()
            } else {
                interactiveTransition.cancelInteractiveTransition()
            }
        default:
            break
        }
    }
}

最后,在 presenting 视图控制器中,设置 modalPresentationStyle.custom,并提供转场代理:

swift
class PresentingViewController: UIViewController, UIViewControllerTransitioningDelegate {
    let interactiveTransition = InteractiveDismissalTransition()

    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
        return CustomPresentationController(presentedViewController: presented, presenting: presenting)
    }

    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CustomPresentationAnimator()
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CustomDismissalAnimator()
    }

    func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
        return interactiveTransition.interactionInProgress ? interactiveTransition : nil
    }

    @IBAction func presentButtonTapped(_ sender: UIButton) {
        let modalVC = ModalViewController()
        modalVC.transitioningDelegate = self
        modalVC.modalPresentationStyle = .custom
        present(modalVC, animated: true, completion: nil)
    }
}

交互式转场的注意事项

  • 性能优化: 避免在转场过程中进行复杂的计算,以免影响动画的流畅性。
  • 用户反馈: 提供清晰的用户反馈,例如在转场过程中改变视图的透明度或大小。
  • 边界处理: 处理好手势取消和完成的情况,确保转场动画的完整性。

总结

通过创建交互式转场,你可以为你的应用增加更多的互动性和趣味性。记住,良好的用户体验是成功的关键!🚀 尝试不同的手势和动画效果,打造独一无二的转场体验吧!

本站使用 VitePress 制作