ActionSheet点击对应索引后打开错误索引问题
问题:LazyVGrid中点击按钮后,ConfirmationDialog始终关联错误的索引
现象描述
点击LazyVGrid里对应索引的三点按钮时,弹出的ConfirmationDialog(原ActionSheet)始终指向错误的文件夹条目,无法匹配当前点击的项。
问题原因
所有MenuButton都绑定了同一个全局的isActionSheetShow状态变量。当任意按钮触发这个状态时,所有弹窗都会响应,但实际只会显示某一个固定条目的弹窗——因为没有为每个条目设置独立的状态控制。
解决方案
为每个文件夹条目添加独立的弹窗状态,让每个按钮对应自己的弹窗开关。下面提供两种实现方式:
方式1:修改数据模型添加状态属性
如果允许修改FolderModel,直接给模型添加弹窗状态属性:
// 修改FolderModel,添加独立的弹窗状态 struct FolderModel: Identifiable { let id: UUID var folderName: String var isActionSheetShown = false // 新增:控制当前条目弹窗的显示 // 其他原有属性... }
然后更新视图代码:
LazyVGrid(columns: SizeConfig.GridLayout.adaptiveGridItemLayout_140) { // 使用绑定数组遍历,直接修改每个条目的状态 ForEach($folderData) { $folderItem in MakeGridFolders(folderData: $folderItem) } } @ViewBuilder private func MakeGridFolders(folderData: Binding<FolderModel>)-> some View { NavigationLink(destination: FilesView()) { VStack() { Image(App.Image.fileIcon_Light) HStack { Text(folderData.folderName.wrappedValue) Spacer() // 绑定到当前条目的isActionSheetShown属性 MenuButton(isActionSheetShow: folderData.isActionSheetShown, action: { folderData.isActionSheetShown.toggle() }) } } } } struct MenuButton: View { @Binding var isActionSheetShow: Bool var action: () -> Void var body: some View { VStack { Button { action() } label: { Image(icon) // 确保icon是已定义的图片资源 } .confirmationDialog("", isPresented: $isActionSheetShow, titleVisibility: .hidden) { // 这里添加你的弹窗操作按钮,示例: Button("重命名") { /* 处理当前条目的重命名逻辑 */ } Button("删除", role: .destructive) { /* 处理当前条目的删除逻辑 */ } Button("取消", role: .cancel) { } } } }
方式2:用字典维护状态(不修改模型)
如果不想修改FolderModel,可以用字典来单独记录每个条目的弹窗状态:
// 在父视图中添加状态字典 @State private var actionSheetStates: [UUID: Bool] = [:] @State private var folderData: [FolderModel] // 初始化时为每个条目设置初始状态 init(folderData: [FolderModel]) { self.folderData = folderData for folder in folderData { actionSheetStates[folder.id] = false } } // 更新LazyVGrid遍历代码 LazyVGrid(columns: SizeConfig.GridLayout.adaptiveGridItemLayout_140) { ForEach(folderData) { folderItem in // 绑定到字典中对应id的状态 MakeGridFolders(folderData: folderItem, isActionSheetShow: $actionSheetStates[folderItem.id, default: false]) } } @ViewBuilder private func MakeGridFolders(folderData: FolderModel, isActionSheetShow: Binding<Bool>)-> some View { NavigationLink(destination: FilesView()) { VStack() { Image(App.Image.fileIcon_Light) HStack { Text(folderData.folderName) Spacer() MenuButton(isActionSheetShow: isActionSheetShow, action: { isActionSheetShow.wrappedValue.toggle() }) } } } } // MenuButton代码无需修改,保持原结构即可
核心修改点
- 取消全局状态的共享,为每个条目分配独立的弹窗控制变量
- 通过绑定传递状态,确保点击操作只影响当前条目的弹窗显示
内容的提问来源于stack exchange,提问作者Vikash Kumar Chaubey
相关产品推荐
相关产品推荐

