You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI实现从C页面侧滑返回直接回到A页面(跳过B页面)的方法

SwiftUI侧滑返回从C直接到A(跳过B)的无动画异常解决方案

要实现从C页面侧滑返回直接回到A页面且无异常动画,核心思路是保留正常的页面跳转动画,同时拦截返回操作的路径修改:

  1. 从B到C时使用正常的path.append(.viewC),确保进入C页面时有标准的push动画。
  2. 在C页面监听导航路径的变化,当系统自动将路径回退到[.viewA, .viewB]时,直接将路径重置为[.viewA],触发从C到A的pop动画,跳过B页面。

修改后的完整代码如下:

import SwiftUI

enum Route {
    case viewA, viewB, viewC
}

struct ContentView: View {
    @State private var path: [Route] = []

    var body: some View {
        NavigationStack(path: $path) {
            Text("This is root view")
            Button {
                path.append(.viewA)
            } label: {
                Text("Go to screen A")
            }
            .navigationDestination(for: Route.self) { route in
                switch route {
                case .viewA:
                    AView(path: $path)
                case .viewB:
                    BView(path: $path)
                case .viewC:
                    CView(path: $path)
                }
            }
        }
    }
}

struct AView: View {
    @Binding var path: [Route]

    var body: some View {
        VStack {
            Text("This is Screen A")
            Button("Go to Screen B") {
                path.append(.viewB)
            }
        }
    }
}

struct BView: View {
    @Binding var path: [Route]

    var body: some View {
        VStack {
            Text("This is Screen B")
            Button("Go to Screen C") {
                path.append(.viewC) // 保留正常push动画
            }
        }
    }
}

struct CView: View {
    @Binding var path: [Route]
    @State private var isHandlingBack = false // 防止重复触发路径修改

    var body: some View {
        VStack {
            Text("This is Screen C")
        }
        .onChange(of: path) { newPath in
            guard !isHandlingBack else {
                isHandlingBack = false
                return
            }
            // 拦截返回操作:当路径回到包含B的状态时,直接跳转到A
            if newPath == [.viewA, .viewB] {
                isHandlingBack = true
                withAnimation {
                    path = [.viewA]
                }
            }
        }
    }
}

#Preview {
    ContentView()
}

关键说明:

  • 正常跳转动画:从B到C使用append,确保系统播放标准的push过渡动画,解决了之前直接替换路径导致无动画的问题。
  • 拦截返回逻辑:通过onChange监听路径变化,当用户触发侧滑或点击返回按钮时,系统会先将路径回退到[.viewA, .viewB],此时我们立即将路径重置为[.viewA],系统会自动播放从C到A的pop动画,不会出现到B页面的中间状态。
  • 防止循环触发:使用isHandlingBack状态标记,避免路径修改后再次触发onChange导致的循环问题。

内容的提问来源于stack exchange,提问作者akhsary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 07:34:51