自定义转场

在iOS中,自定义转场动画可以通过实现 UIViewControllerAnimatedTransitioning 协议来为模态(modal)和推送(push)转场提供自定义动画。以下是这两种转场的具体实现方式:

1. 自定义模态转场

Step 1: 创建转场代理

创建一个遵循 UIViewControllerAnimatedTransitioning 协议的类:

import UIKit

class CustomModalTransition: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5 // 设置转场的持续时间
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let fromViewController = transitionContext.viewController(forKey: .from),
              let toViewController = transitionContext.viewController(forKey: .to) else { return }
        
        let containerView = transitionContext.containerView
        containerView.addSubview(toViewController.view)
        
        // 设置初始状态
        toViewController.view.alpha = 0.0
        
        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            // 进行动画
            toViewController.view.alpha = 1.0
        }) { _ in
            // 完成转场
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        }
    }
}

Step 2: 设置转场代理

在要展示模态的 ViewController 中设置转场代理:

class FirstViewController: UIViewController, UIViewControllerTransitioningDelegate {
    func presentModal() {
        let secondVC = SecondViewController()
        secondVC.modalPresentationStyle = .custom
        secondVC.transitioningDelegate = self
        present(secondVC, animated: true, completion: nil)
    }

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

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CustomModalTransition() // 也可以实现dismiss动画
    }
}

2. 自定义推送转场

Step 1: 创建转场代理

创建一个遵循 UIViewControllerAnimatedTransitioning 协议的类,类似于模态转场:

class CustomPushTransition: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let fromViewController = transitionContext.viewController(forKey: .from),
              let toViewController = transitionContext.viewController(forKey: .to) else { return }
        
        let containerView = transitionContext.containerView
        containerView.addSubview(toViewController.view)
        
        // 设置初始状态
        toViewController.view.transform = CGAffineTransform(translationX: containerView.bounds.width, y: 0)
        
        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            // 进行动画
            fromViewController.view.transform = CGAffineTransform(translationX: -containerView.bounds.width, y: 0)
            toViewController.view.transform = .identity
        }) { _ in
            // 完成转场
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        }
    }
}

Step 2: 设置转场代理

在使用 UINavigationControllerViewController 中设置转场代理:

class FirstViewController: UIViewController, UINavigationControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        navigationController?.delegate = self
    }

    func pushNextViewController() {
        let nextVC = SecondViewController()
        navigationController?.pushViewController(nextVC, animated: true)
    }

    func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        if operation == .push {
            return CustomPushTransition()
        }
        return nil
    }
}
posted @   looxy  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示