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

SwiftUI中NavigationLinks优化及区域数据传递问题咨询

解决方案:统一导航逻辑+消除冗余视图

1. 先梳理数据关联逻辑

首先给Region结构体加一个标识字段,用来和对应区域的Shrine数组绑定:

struct Region: Identifiable {
    var id: String
    let regionName: String
    let regionImage: String
    let shrineAmount: Int
    let regionKey: String // 新增:用来匹配对应区域的Shrine数据,比如"akkala"、"centralHyrule"
}

然后调整ShrineList,增加一个通过regionKey获取对应数据的方法:

struct ShrineList {
    static var akkala: [Shrine] = [
        // Akkala区域的Shrine数据
    ]
    static var centralHyrule: [Shrine] = [
        // CentralHyrule区域的Shrine数据
    ]
    
    // 根据regionKey返回对应区域的Shrine数组
    static func getShrines(for key: String) -> [Shrine] {
        switch key {
        case "akkala":
            return akkala
        case "centralHyrule":
            return centralHyrule
        // 后续新增区域直接加case即可
        default:
            return []
        }
    }
}

2. 写一个通用的Shrine列表视图

不用每个区域单独写视图,所有区域共用这一个:

struct ShrineListView: View {
    let shrineData: [Shrine]
    @EnvironmentObject var completed: Favorites
    
    var body: some View {
        List(shrineData) { shrine in
            // 这里写单个Shrine的单元格布局,示例如下
            HStack {
                Image(shrine.imageName)
                    .resizable()
                    .frame(width: 50, height: 50)
                VStack(alignment: .leading) {
                    Text(shrine.title)
                        .font(.headline)
                    Text(shrine.location)
                        .font(.caption)
                }
                Spacer()
                Image(systemName: shrine.isCompleted ? "checkmark.circle.fill" : "circle")
                    .foregroundColor(shrine.isCompleted ? .green : .gray)
            }
        }
        .navigationTitle("Shrines")
    }
}

3. 重构Region列表单元格

把原来的单元格代码提取成单独视图,让主视图更简洁:

struct RegionListItemView: View {
    let region: Region
    
    var body: some View {
        ZStack {
            Image(region.regionImage)
                .resizable()
                .scaledToFill()
                .frame(width: 420, height: 100)
            Color.black
                .frame(width: 400, height: 100)
                .opacity(0.1)
            
            HStack(spacing: 2) {
                VStack(alignment: .leading, spacing: 1) {
                    Text(region.regionName)
                        .font(.system(size: 25, weight: .bold))
                        .lineLimit(1)
                        .minimumScaleFactor(0.8)
                        .foregroundColor(.white)
                        .shadow(radius: 2)
                    
                    Text("\(region.shrineAmount) Shrines")
                        .font(.system(size: 12, weight: .medium))
                        .foregroundColor(.white)
                }
                .padding(.leading, 40)
                Spacer()
            }
        }
    }
}

4. 修改主视图的导航逻辑

现在可以动态绑定数据,不用硬编码每个区域的视图:

struct RegionViewOpt: View {
    @StateObject var completed = Favorites()
    @State private var regionlist: [Region] = RegionList.regions
    
    var body: some View {
        // iOS16+推荐用NavigationStack替代NavigationView
        NavigationStack {
            List(regionlist) { region in
                NavigationLink(
                    destination: ShrineListView(shrineData: ShrineList.getShrines(for: region.regionKey))
                ) {
                    RegionListItemView(region: region)
                }
                .listRowSeparator(.hidden)
            }
            .navigationTitle("Regions")
        }
        .environmentObject(completed)
    }
}

核心逻辑说明

  • 通过regionKey建立区域和Shrine数据的绑定,新增区域时只需要给Region加对应key、给ShrineList加对应数组和case即可
  • 通用视图复用列表逻辑,彻底消除冗余代码
  • 单元格抽离后,主视图结构更清晰,后续修改样式也更方便

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:01:04