SwiftUI中如何触发一个视图的按钮并带动另一个视图的对象动画?
SwiftUI卡片按钮触发动画失效问题解决
我正在实现动画逻辑,目标是点击按钮时让卡片滑走,但当前使用@State和Binding的方案没有效果,推测问题在于卡片视图未感知到按钮的状态触发。
按钮代码
Button(action: { // Handle button action // isTapped.toggle() isFLipped.toggle() }) { Text("👍") .frame(width: 70, height: 50) .background(Color("Easy")) .clipShape(RoundedRectangle(cornerRadius: 8)) }
SingleCardView代码
ZStack { RoundedRectangle(cornerRadius: 25, style: .continuous) .fill(Color.white) .overlay(RoundedRectangle(cornerRadius: 25).stroke(getColor(), lineWidth: 2))// 根据滑动方向改变边框颜色 .shadow(radius: 3) VStack { NavigationStack { Text(card.term ?? "Unnamed Card") Divider() if isTapped { Text(card.definition ?? "Unnamed Card") } } } } .frame(width: 300, height: 500) .rotation3DEffect( Angle(degrees: isFLipped ? 360: 0), axis: (x: 0, y: isFLipped ? 360 : 0, z: 0) ) .onTapGesture { isTapped.toggle() }
核心问题与修复步骤
问题根源是按钮所在视图的isFLipped状态和SingleCardView的状态是独立的两个变量,必须通过@Binding将父视图的状态传递给子视图,才能实现状态同步。
- 修改
SingleCardView,将内部的isFLipped改为@Binding:
struct SingleCardView: View { let card: Card // 替换为你的卡片数据模型 @Binding var isFLipped: Bool @State private var isTapped = false // 保留你原有的getColor()实现 func getColor() -> Color { // 你的颜色逻辑 return .gray } var body: some View { // 原有视图结构保持不变 ZStack { RoundedRectangle(cornerRadius: 25, style: .continuous) .fill(Color.white) .overlay(RoundedRectangle(cornerRadius: 25).stroke(getColor(), lineWidth: 2)) .shadow(radius: 3) VStack { NavigationStack { Text(card.term ?? "Unnamed Card") Divider() if isTapped { Text(card.definition ?? "Unnamed Card") } } } } .frame(width: 300, height: 500) .rotation3DEffect( Angle(degrees: isFLipped ? 360: 0), axis: (x: 0, y: isFLipped ? 360 : 0, z: 0) ) .onTapGesture { isTapped.toggle() } } }
- 在父视图中,将
@State修饰的isFLipped通过绑定传递给SingleCardView:
struct ParentView: View { @State private var isFLipped = false let card: Card // 你的卡片数据 var body: some View { VStack { // 使用$传递绑定 SingleCardView(card: card, isFLipped: $isFLipped) Button(action: { isFLipped.toggle() }) { Text("👍") .frame(width: 70, height: 50) .background(Color("Easy")) .clipShape(RoundedRectangle(cornerRadius: 8)) } } } }
实现"滑走"动画(可选)
如果你的需求是卡片滑出屏幕而非旋转,可将rotation3DEffect替换为以下动画:
.offset(x: isFLipped ? UIScreen.main.bounds.width : 0) .opacity(isFLipped ? 0 : 1) .animation(.easeInOut(duration: 0.5), value: isFLipped)
内容的提问来源于stack exchange,提问作者Kolea
相关产品推荐
相关产品推荐

