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

SwiftUI Sheet数组数据显示异常:点击项未正确展示

SwiftUI列表滑动触发Sheet始终显示最后一项,如何解决?

问题代码

import SwiftUI

struct MyView: View {
    @State private var items = ["Apple", "Microsoft", "Google"]
    @State private var presentSheet = false

    var body: some View {
        NavigationStack {
            List {
                ForEach(items, id: \.self) { item in 
                    Text(item)
                        .swipeActions(edge: .leading) {
                            Button("Show", systemImage: "eye") {
                                presentSheet.toggle()
                            }
                            .tint(Color.yellow)
                        }
                        .sheet(isPresented: $presentSheet) {
                            Text(item)
                        }
                }
            }
            .navigationTitle("MyView")
        }
    }
}

问题说明

无论点击哪个列表项的滑动按钮触发Sheet,Sheet始终显示数组最后一项(如"Google"),而非触发操作的对应项。需求是让Sheet展示当前选中的列表项内容。

问题原因

  1. 所有列表项共用同一个布尔状态presentSheet,无法区分触发源
  2. Sheet直接引用循环变量item,SwiftUI循环结束后item会保留最后一次迭代的值,导致Sheet始终显示最后一项

解决方法

改用sheet(item:)API,绑定存储选中项的可选状态变量,让SwiftUI自动管理Sheet的显示与对应内容:

修改后的代码

import SwiftUI

struct MyView: View {
    @State private var items = ["Apple", "Microsoft", "Google"]
    // 存储选中项的状态变量,nil表示不显示Sheet
    @State private var selectedItem: String?

    var body: some View {
        NavigationStack {
            List {
                ForEach(items, id: \.self) { item in 
                    Text(item)
                        .swipeActions(edge: .leading) {
                            Button("Show", systemImage: "eye") {
                                // 点击时赋值当前项,触发Sheet显示
                                selectedItem = item
                            }
                            .tint(Color.yellow)
                        }
                }
            }
            .navigationTitle("MyView")
            // 绑定选中项,非nil时自动显示Sheet
            .sheet(item: $selectedItem) { selectedItem in
                Text(selectedItem)
            }
        }
    }
}

// 为String扩展Identifiable协议,满足sheet(item:)的要求
extension String: Identifiable {
    public var id: String { self }
}

代码说明

  1. selectedItem状态变量专门存储当前选中的列表项,通过赋值操作触发Sheet显示
  2. .sheet(item:)API会根据selectedItem是否为nil自动控制Sheet的显示/隐藏,且Sheet内容直接绑定选中的具体项,不会受循环变量生命周期影响
  3. 扩展String实现Identifiable协议,是因为sheet(item:)要求绑定对象必须遵循该协议(如果使用自定义模型,直接让模型遵循协议即可)

内容的提问来源于stack exchange,提问作者Victor Vaknin Otte Hansen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 10:35:04