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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:36:20