SwiftUI中利用.rotation3DEffect实现多视图翻转切换
多视图圆形翻转动画实现方案(SwiftUI)
你的现有代码存在视图重复实现、状态管理繁琐的问题,导致翻转动画逻辑混乱。以下是优化后的实现,支持任意数量视图的平滑翻转切换:
核心优化点
- 封装通用圆形视图,消除重复代码
- 用枚举管理当前显示视图,替代大量Bool状态变量
- 简化翻转动画逻辑,确保切换过程平滑自然
完整代码
// 通用圆形视图,统一实现样式和旋转效果 struct ColoredCircleView: View { let color: Color let text: String @Binding var rotationDegree: Double var body: some View { ZStack { Circle() .frame(width: 350, height: 350) .foregroundColor(color) Text(text) .foregroundColor(.black) .font(.title) } .rotation3DEffect( Angle(degrees: rotationDegree), axis: (x: 0, y: 1, z: 0), perspective: 0.2 ) } } // 枚举标记当前显示的视图 enum CurrentView { case teal, red, blue, yellow } struct ContentView: View { @State private var currentView: CurrentView = .teal @State private var rotationDegree: Double = 0 @State private var isTransitioning = false let animationDuration: Double = 0.45 // 切换视图并执行翻转动画 func switchToView(_ newView: CurrentView) { guard currentView != newView, !isTransitioning else { return } isTransitioning = true // 第一步:将当前视图转到90度(不可见) withAnimation(.easeInOut(duration: animationDuration)) { rotationDegree = 90 } // 第二步:切换视图,再将新视图转到0度 DispatchQueue.main.asyncAfter(deadline: .now() + animationDuration) { currentView = newView withAnimation(.easeInOut(duration: animationDuration)) { rotationDegree = 0 } isTransitioning = false } } var body: some View { VStack { // 根据当前状态显示对应视图 switch currentView { case .teal: ColoredCircleView( color: .systemTeal, text: "Teal View!", rotationDegree: $rotationDegree ) case .red: ColoredCircleView( color: .systemRed, text: "Red View!", rotationDegree: $rotationDegree ) case .blue: ColoredCircleView( color: .systemBlue, text: "Blue View!", rotationDegree: $rotationDegree ) case .yellow: ColoredCircleView( color: .systemYellow, text: "Yellow View!", rotationDegree: $rotationDegree ) } HStack(spacing: 20) { // 切换按钮 Button { switchToView(.teal) } label: { ZStack { Circle() .foregroundColor(.systemTeal) .frame(width: 60, height: 60) Text("Teal") .foregroundColor(.black) } } Button { switchToView(.red) } label: { ZStack { Circle() .foregroundColor(.systemRed) .frame(width: 60, height: 60) Text("Red") .foregroundColor(.black) } } Button { switchToView(.blue) } label: { ZStack { Circle() .foregroundColor(.systemBlue) .frame(width: 60, height: 60) Text("Blue") .foregroundColor(.black) } } Button { switchToView(.yellow) } label: { ZStack { Circle() .foregroundColor(.systemYellow) .frame(width: 60, height: 60) Text("Yellow") .foregroundColor(.black) } } } .padding(.top, 30) } .padding() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
代码说明
- 通用视图封装:
ColoredCircleView将圆形样式、文本、旋转效果统一封装,新增视图只需传入颜色和文本即可,无需重复编写布局代码。 - 状态管理简化:用
CurrentView枚举记录当前显示的视图,替代原来的多个Bool变量,状态逻辑更清晰,避免出错。 - 动画逻辑优化:翻转动画分为两步:先将当前视图旋转到90度(视觉上消失),切换视图后再将新视图旋转回0度,确保过渡过程平滑自然,且同一时间只执行一次动画。
内容的提问来源于stack exchange,提问作者AdvocateUK
相关产品推荐
相关产品推荐

