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

NavigationSplitView侧边栏点击后详情页不显示问题求助

解决NavigationSplitView点击侧边栏条目后详情区不显示对应内容的问题

问题根源

你的代码存在两个核心问题:

  1. 侧边栏的ItemList没有与ItemSplitView中的selectedItem绑定,导致点击条目时无法将选中的Item传递到详情区。
  2. EditItemView中的title和desc状态变量未从传入的item初始化,所以即使选中了Item,详情区也不会显示对应内容。

修复步骤

1. 给ItemList添加选中项绑定

修改ItemSplitView中ItemList的调用,传入selectedItem的绑定:

ItemList(sortOrder: sortOrder, filterString: filter, selectedItem: $selectedItem)

同时修改ItemList的定义,接收绑定参数并在内部List中启用选中绑定:

struct ItemList: View {
    let sortOrder: SortOrder
    let filterString: String
    @Binding var selectedItem: Item? // 添加选中项绑定
    
    // 你的SwiftData查询逻辑...
    
    var body: some View {
        List(/* 查询到的Item数组 */, selection: $selectedItem) { item in
            // 列表行内容,例如:Text(item.title)
        }
    }
}

2. 初始化EditItemView的状态变量

在EditItemView中,从传入的item初始化title和desc状态变量,有两种方式可选:

方式一:通过初始化器初始化

struct EditItemView: View {
    @Environment(\.dismiss) private var dismiss
    @Bindable var item: Item
    @Binding var navigationPath: NavigationPath
    
    @State private var title: String
    @State private var desc: String
    
    init(item: Item, navigationPath: Binding<NavigationPath>) {
        self.item = item
        self._navigationPath = navigationPath
        self._title = State(initialValue: item.title)
        self._desc = State(initialValue: item.desc) // 假设Item有desc属性
    }

    // 原有body内容...
}

方式二:通过onAppear初始化

struct EditItemView: View {
    @Environment(\.dismiss) private var dismiss
    @Bindable var item: Item
    @Binding var navigationPath: NavigationPath
    
    @State private var title = ""
    @State private var desc = ""

    var body: some View {
        Form {
            // 原有表单内容...
        }
        .onAppear {
            title = item.title
            desc = item.desc
        }
    }
}

3. 可选:添加编辑保存逻辑

如果需要将用户修改的内容同步回Item,可以添加保存按钮:

// 在EditItemView的Form中添加保存按钮
Button(action: {
    item.title = title
    item.desc = desc
    dismiss()
}) {
    HStack {
        Text("Save")
            .font(.body)
            .foregroundColor(.blue)
        Image(systemName: "checkmark.circle")
            .font(.body)
            .foregroundColor(.blue)
    }
    .padding(.vertical)
}
.disabled(!changed) // 内容未变化时禁用按钮

完整修改后的关键代码片段

修改后的ItemSplitView

struct ItemSplitView: View {
    @Environment(\.modelContext) private var context
    @State private var sortOrder = SortOrder.title
    @State private var filter = ""
    @State private var selectedItem: Item? = nil
    @State private var path = NavigationPath()
    @State private var isPresented: Bool = false
    
    var body: some View {
        NavigationSplitView {
            ItemList(sortOrder: sortOrder, filterString: filter, selectedItem: $selectedItem)
                .listStyle(SidebarListStyle())
                .navigationTitle("Items")
                .toolbar {
                    ToolbarItem(placement: .topBarTrailing) {
                        Picker("", selection: $sortOrder) {
                            ForEach(SortOrder.allCases) { sortOrder in
                                Text("Sort by \(sortOrder.rawValue)").tag(sortOrder)
                            }
                        }
                    }
                }
                .searchable(text: $filter, prompt: Text("full text search"))
                .sheet(isPresented: $isPresented) {
                    UserPropertiesScreen(isPresented: $isPresented)
                }
        } detail: {
            if let selectedItem = selectedItem {
                EditItemView(item: selectedItem, navigationPath: $path)
            } else {
                Text("Select an item from the sidebar")
            }
        }
    }
}

修改后的EditItemView

struct EditItemView: View {
    @Environment(\.dismiss) private var dismiss
    @Bindable var item: Item
    @Binding var navigationPath: NavigationPath
    
    @State private var title: String
    @State private var desc: String
    
    init(item: Item, navigationPath: Binding<NavigationPath>) {
        self.item = item
        self._navigationPath = navigationPath
        self._title = State(initialValue: item.title)
        self._desc = State(initialValue: item.desc)
    }

    var body: some View {
        Form {
            Section {
                LabeledContent {
                    TextField("", text: $title)
                } label: {
                    Text("Title").foregroundStyle(.secondary)
                }
                TextEditor(text: $desc)
            }
            
            Button(action: {
                item.title = title
                item.desc = desc
                dismiss()
            }) {
                HStack {
                    Text("Save")
                        .font(.body)
                        .foregroundColor(.blue)
                    Image(systemName: "checkmark.circle")
                        .font(.body)
                        .foregroundColor(.blue)
                }
                .padding(.vertical)
            }
            .disabled(!changed)
            
            Button(action: {
                dismiss()
            }) {
                HStack{
                    Text("Cancel").font(.body)
                        .foregroundColor(Color("MoRed3"))
                    Image(systemName: "xmark.circle").font(.body)
                        .foregroundColor(Color("MoRed3"))
                }
                .padding (.vertical)
            }
        }
        .navigationBarItems(leading: Button(action: {
            dismiss()
        }) {
            Text("Cancel").font(.body)
            Image(systemName: "xmark.circle").font(.body)
        })
    }
    
    var changed: Bool {
        title != item.title || desc != item.desc
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:42:13