如何在SwiftUI动画中反转slide滑动转场的播放方向?
解决方案
你需要使用**不对称转场(Asymmetric Transition)**分别定义视图的入场和离场方向,就能实现右进左出的滑动效果,不需要全局修改语言方向。
你之前单独使用.move(edge: .trailing)不符合预期,是因为单一的move转场会让视图的入场和离场都作用在同一个边缘,所以出现进出都从右侧走的问题。
直接把所有页面的.transition(.slide)替换为如下代码即可:
.transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)))
完整修改后代码
import SwiftUI struct ContentView: View { enum screens { case start, mid, final } @State var curScreen: screens = .start func changeScreen() { switch curScreen { case .start: curScreen = .mid case .mid: curScreen = .final case .final: return } } var body: some View { switch curScreen { case .start: ScreenView(callback: changeScreen, text: "Start") .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading))) case .mid: ScreenView(callback: changeScreen, text: "Mid") .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading))) case .final: ScreenView(callback: {}, text: "Final") .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading))) } } } struct ScreenView: View { let callback: () -> () let text: String var body: some View { Text(text) .padding() .frame(maxWidth: .infinity) .onTapGesture { withAnimation(.default) { callback() } } } }
优化方案
你可以把自定义转场抽成全局扩展,后续使用更简洁:
extension AnyTransition { static let reverseSlide = Self.asymmetric( insertion: .move(edge: .trailing), removal: .move(edge: .leading) ) } // 后续所有页面直接调用即可 .transition(.reverseSlide)
内容的提问来源于stack exchange,提问作者noranraskin
相关产品推荐
相关产品推荐

