移动端旧页面缩小带圆角的页面转场动画叫什么?如何实现?
这类动画的正式名称
这类转场的标准名称是 缩放式模态转场(Zoom Modal Transition),在iOS生态中也常被称为卡片式模态转场,是iOS 13之后系统内置的默认模态弹出交互,目前安卓、各类跨端框架也都普遍采用这套交互范式。
效果演示如下:
实现思路
你观察到的上级页面缩小、生成圆角、状态栏变黑三个特征,是转场过程中三个并行执行的动画效果,总动画时长建议设置为0.25~0.3s,使用ease-out缓动曲线即可还原原生流畅度,核心拆解逻辑如下:
- 底层旧页面处理:转场触发后,给即将被覆盖的上级页面做两个属性变换:① 整体等比缩放至原尺寸的0.92~0.94倍;② 给页面根容器添加12~16px的圆角,开启裁切隐藏超出圆角的内容。注意圆角要加在整页容器上,不要仅加在内容区域,避免导航栏、状态栏区域漏出直角边。
- 遮罩与状态栏处理:在旧页面和新页面之间插入一层纯黑色半透明遮罩,遮罩透明度从0线性过渡到0.35~0.4;同步将状态栏样式切换为深色(黑色),和整体变暗的底层视觉统一。
- 上层新页面处理:新页面初始位置放在屏幕底部外(y轴偏移量等于页面自身高度),动画过程中向上滑动到完全覆盖屏幕的位置,页面顶部同样配置和底层匹配的圆角,层级放在遮罩之上。
如果是iOS原生开发,可以直接通过自定义UIViewControllerAnimatedTransitioning实现上述逻辑,核心代码参考:
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { guard let fromVC = transitionContext.viewController(forKey: .from), let toVC = transitionContext.viewController(forKey: .to) else { return } let container = transitionContext.containerView let animDuration = transitionDuration(using: transitionContext) // 初始化遮罩和新页面 let dimmingLayer = UIView(frame: container.bounds) dimmingLayer.backgroundColor = .black dimmingLayer.alpha = 0 container.addSubview(dimmingLayer) toVC.view.frame = container.bounds.offsetBy(dx: 0, dy: container.bounds.height) toVC.view.layer.cornerRadius = 16 toVC.view.clipsToBounds = true container.addSubview(toVC.view) // 执行并行动画 UIView.animate(withDuration: animDuration, delay: 0, options: .curveEaseOut) { fromVC.view.transform = CGAffineTransform(scaleX: 0.93, y: 0.93) fromVC.view.layer.cornerRadius = 16 fromVC.view.clipsToBounds = true dimmingLayer.alpha = 0.4 toVC.view.frame = container.bounds UIApplication.shared.statusBarStyle = .darkContent } completion: { finished in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) } }
如果是跨端开发(Flutter、React Native等),不需要从零手写动画,直接使用框架内置的模态组件即可:Flutter可配置showModalBottomSheet的相关参数,React Native可使用react-native-modal组件,调整缩放比例、圆角、遮罩透明度三个参数就能还原一致效果。
内容的提问来源于stack exchange,提问作者Valentyna P
相关产品推荐
相关产品推荐

