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

SwiftUI使用NavigationLink时出现双返回按钮问题求助

SwiftUI 导航返回按钮重复叠加问题修复

问题根源

你遇到的两个返回按钮叠加问题,核心原因是重复嵌套了NavigationView:

  • 顶层的Marketplace视图已经初始化了全局导航容器
  • ShoeSeeAllView里又额外创建了一个NavigationView,导致导航栈被多层包裹,系统渲染出两个导航栏

修复方案

只需要移除ShoeSeeAllView中的NavigationView,调整导航标题的应用位置,同时优化ShoeRowView的NavigationLink写法即可:

修改后的完整代码

struct Marketplace: View {
    var body: some View {
        NavigationView {
            MarketplaceShoesView()
        }
    }
}

struct MarketplaceShoesView: View {
    // 示例数据,可替换为你的实际数据
    let shoe = ShoeRow(title: "热门鞋款", id: "1", shoes: [ShoeStruct(id: "101"), ShoeStruct(id: "102")])
    
    var body: some View {
        ScrollView {
            ShoeRowView(shoeData: shoe)
        }
    }
}

struct ShoeRowView: View {
    @State private var isShowingDetailView = false
    var shoeData: ShoeRow
    
    var body: some View {
        VStack {
            HStack {
                Text(shoeData.title)
                Spacer() // 让按钮自动靠右,优化布局
                
                Button(action: {
                    isShowingDetailView = true
                }) {
                    HStack(spacing: 4) {
                        Text("See All")
                        Image(systemName: "chevron.right")
                    }
                }
                // 隐藏空的NavigationLink标签,避免布局干扰
                NavigationLink(
                    destination: ShoesSeeAllView(shoeData: shoeData, shoe_id: shoeData.id),
                    isActive: $isShowingDetailView
                ) {
                    EmptyView()
                }
                .hidden()
            }
            .padding()
            
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 20) {
                    ForEach(shoeData.shoes ?? []) { shoe in
                        Text("Name of shoes")
                    }
                }
                .padding()
            }
            Divider()
        }
    }
}

// 移除内部嵌套的NavigationView
struct ShoesSeeAllView: View {
    var shoeData: ShoeRow
    var shoe_id: String
    
    var body: some View {
        ScrollView(.vertical, showsIndicators: false) {
            VStack(spacing: 25) {
                ForEach(shoeData.shoes ?? []) { shoe in
                    ShoeViewLong(shoeData: shoe)
                }
            }
            .padding()
        }
        .navigationTitle(shoeData.title) // 将导航标题直接绑定到当前视图
    }
}

struct ShoeViewLong: View {
    var shoeData: ShoeStruct
    
    var body: some View {
        NavigationLink(destination: ShoeDetailView(shoe_id: shoeData.id ?? "")) {
            HStack(spacing: 12) {
                Image("ShoeImage")
                    .resizable()
                    .frame(width: 80, height: 80) // 给图片添加固定尺寸,避免布局异常
                Text("Shoes Name")
                Spacer()
                Image(systemName: "chevron.right")
                    .foregroundColor(.gray)
            }
            .padding()
            .background(Color(.systemGray6))
            .cornerRadius(12)
        }
    }
}

struct ShoeDetailView: View {
    var shoe_id: String
    var body: some View {
        Text("This is shoes detail view for ID: \(shoe_id)")
            .navigationTitle("鞋款详情")
    }
}

// 补充你用到的数据结构示例
struct ShoeRow: Identifiable {
    var id: String
    var title: String
    var shoes: [ShoeStruct]?
}

struct ShoeStruct: Identifiable {
    var id: String?
}

修复后导航流程

点击ShoeRowView的"See All" → 进入ShoesSeeAllView(显示单个返回按钮)
点击ShoeViewLong → 进入ShoeDetailView(显示单个返回按钮)
点击返回按钮 → 回到ShoesSeeAllView,再次点击返回 → 回到MarketplaceShoesView,完全符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 17:22:21