UIImageView图片切换动画在UIVisualEffectView覆盖时失效问题求助
解决UIVisualEffectView覆盖下UIImageView淡入淡出动画失效的问题
我之前也踩过一模一样的坑!当UIVisualEffectView覆盖在UIImageView上时,直接用UIView transitionWithView:做图片切换动画会完全失效,本质原因是UIVisualEffectView内部会缓存其底层视图的快照,动画过程中它不会实时更新这个缓存,导致模糊效果完全跟不上图片的过渡,看起来就像动画没执行一样。
用视图快照的思路完全找对方向了,下面是具体的实现步骤和代码,亲测有效:
核心思路
我们先把当前的完整视觉状态(包含UIImageView的图片和UIVisualEffectView的模糊效果)拍个快照,用这个快照临时覆盖在视图上方;然后在后台悄悄更新UIImageView的图片;最后通过淡出快照的方式,平滑过渡到新的视觉状态,完美模拟原生淡入淡出的效果。
先确认你的视图层级
首先需要把背景图和模糊视图放在同一个父容器里,结构大概是这样:
- parentContainerView(专门的容器视图) - _backgroundArtworkImageView(背景图视图) - blurEffectView(你的UIVisualEffectView,层级在背景图之上)
具体实现代码
// 1. 获取当前容器的完整快照(包含背景图+模糊效果) UIView *currentSnapshot = [parentContainerView snapshotViewAfterScreenUpdates:NO]; currentSnapshot.frame = parentContainerView.bounds; [parentContainerView addSubview:currentSnapshot]; // 2. 立即更新背景图(此时快照在最上层,用户看不到这个变化) _backgroundArtworkImageView.image = blurredImage; // 3. 执行快照的淡出动画,实现淡入淡出效果 [UIView animateWithDuration:ANIMATION_DURATION animations:^{ currentSnapshot.alpha = 0.0; } completion:^(BOOL finished) { // 4. 动画结束后清理快照视图 [currentSnapshot removeFromSuperview]; }];
关键细节说明
- 使用
snapshotViewAfterScreenUpdates:NO:确保获取的是当前屏幕上已经渲染好的内容,不会等待pending的UI更新,保证快照和用户看到的完全一致。 - 父容器的必要性:必须把背景图和模糊视图放在同一个容器里,这样快照才能捕获到完整的视觉效果,单独快照UIImageView是没用的(因为不包含模糊层)。
- 动画逻辑:本质是用旧状态的快照做淡出,露出已经准备好的新状态,视觉上就实现了和原来
transitionWithView:一样的淡入淡出过渡。
如果你不想额外加容器,也可以直接快照整个控制器的view,但这样会包含其他无关内容,所以还是用专门的容器更稳妥。
内容的提问来源于stack exchange,提问作者Andreas Henriksson
相关产品推荐
相关产品推荐

