Xcode 13.1中SwiftUI WindowGroup内视图无法实现过渡动画如何解决
SwiftUI 3.0 底部滑入滑出动画失效修复方案
问题原因
- 动画修饰符挂载位置错误:你将
.animation()修饰符放在了if showCard条件判断内部的Rectangle视图上,当showCard为false时该视图不存在,无法捕获状态变化从而触发过渡动画 - 动画逻辑重复声明:按钮点击事件中已经通过
withAnimation包裹了状态变更逻辑,又在Rectangle上额外添加动画声明,反而会导致动画逻辑冲突失效 - 过渡动画(transition)作用于视图的插入、移除生命周期,需要保证动画声明能感知到状态从false到true、true到false的完整变化过程,放在条件内部的视图上无法满足这个要求
修复方案
直接移除Rectangle上的额外.animation()修饰符即可,withAnimation已经可以正确触发transition定义的滑入滑出效果,修复后代码如下:
import SwiftUI @main struct MainApp: App { @State private var showCard = false var body: some Scene { WindowGroup { TabView { Button("Show Card") { withAnimation(.easeInOut(duration: 1)) { showCard.toggle() } } .tabItem { // 原代码自定义Image替换为系统内置图标方便测试,不影响动画逻辑 Image(systemName: "doc.text.magnifyingglass") Text("scan") } Text("Breakdowns") .tabItem { Image(systemName: "square.stack") Text("breakdowns") } Text("Home") .tabItem { Image(systemName: "person.3") Text("people") } Text("Settings") .tabItem { Image(systemName: "gear") Text("settings") } } .accentColor(.blue) .overlay(alignment: .bottom) { if showCard { Rectangle() .edgesIgnoringSafeArea(.all) .transition(.move(edge: .bottom)) .frame(maxWidth: .infinity, maxHeight: 250) } } } } }
可选替代方案
如果你不想用withAnimation包裹状态变更,也可以将动画修饰符移到TabView(条件视图的父容器)上,按钮点击直接修改状态即可:
// 按钮点击逻辑 Button("Show Card") { showCard.toggle() } // TabView添加动画修饰符 TabView { // ... 原有Tab内容 } .animation(.easeInOut(duration: 1), value: showCard) .overlay(alignment: .bottom) { // ... 原有overlay内容 }
内容的提问来源于stack exchange,提问作者Tunds
相关产品推荐
相关产品推荐

