【问题标题】:How to manipulate the ion-list item using an ActionSheet in SwiftUI?如何在 SwiftUI 中使用 ActionSheet 操作离子列表项?
【发布时间】:2020-04-03 00:53:50
【问题描述】:

我正在尝试使用 ActionSheet 来操作 List 的项目。如何调用作为数据模型一部分的函数(在此示例中为 deleteItem),使用 ActionSheet 并操作所选项目,类似于 .onDelete 所做的事情?

我的视图使用以下代码显示模型中的项目:

struct ItemManager: View {
    @ObservedObject var model: ItemModel

    var body: some View {
        List {
            ForEach(model.items) { item in
                ItemCell(item: item)
            }
            .onDelete { self.model.deleteItem(at: $0) }
        }
    }
}

struct ItemCell: View {
    var item: Item
    @State private var isActionSheetVisible = false
    private var actionSheet: ActionSheet {
        let button1 = ActionSheet.Button.default(Text("Delete")){
            self.isActionSheetVisible = false
        }
        let button2 = ActionSheet.Button.cancel(){
            self.isActionSheetVisible = false
        }
        let buttons = [button1, button2]
        return ActionSheet(title: Text("Actions"), buttons: buttons)
    }

    var body: some View {
        VStack(alignment: .leading) {
            Button(action: {
                self.isActionSheetVisible = true
            }) {
                Text(item.title).font(.headline)
            }.actionSheet(isPresented: self.$isActionSheetVisible) {
                self.actionSheet
            }
        }
    }
}

我的模型有一些简单的属性和一个从集合中删除项目的函数:

struct Item: Identifiable, Equatable  {
    let title: String
    var id: String {
        title
    }
}

class ItemModel: ObservableObject {
    @Published var items: [Item] = [Item(title: "temp.1"), Item(title: "temp.2")]
    public func deleteItem(at indices: IndexSet) {
        indices.forEach { items.remove(at: $0) }
    }
}

extension Item {
    static let previewItem = Item(title: "temp.3")
}

更新:在Item 声明中添加Equatable 以保持一致。

【问题讨论】:

    标签: swiftui actionsheet


    【解决方案1】:

    您可以尝试将ItemModel 传递给ForEach(),如下所示:

    ForEach(model.items) { item in
        ItemCell(item: item, model: self.model)
    }
    

    然后在您的ItemCell 中您可以:

    struct ItemCell: View {
        var item: Item
        var model: ItemModel // Add the model variable
    
        @State private var isActionSheetVisible = false
    
        private var actionSheet: ActionSheet {
            let button1 = ActionSheet.Button.default(Text("Delete")) {
                // Get the index
                if let index = self.model.items.firstIndex(of: self.item) {
                    // Delete the item based on the index
                    self.model.items.remove(at: index)
    
                    // Dismiss the ActionSheet
                    self.isActionSheetVisible = false
                } else {
                    print("Could not find item!")
                    print(self.item)
                }
            }
        }
    }
    

    【讨论】:

    • 非常感谢。它就像一个魅力!我必须在Item 定义中添加Equatable 才能使其工作。我觉得很奇怪,发件人没有被转移到儿童物品上,我们必须经历所有这些才能找到该物品。在单独的说明中,虽然 ActionSheet 存在一个问题,但在删除父项后不会自动关闭。我想,由于我们从列表中删除了该项目,$isActionSheetVisible 没有更新。有关如何解决此问题的任何想法?
    • @jiko ActionSheet 的解雇似乎对我来说很好。您可以做的一件事(我已经更新了答案)是在删除项目后立即关闭 ActionSheet
    猜你喜欢
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 2019-01-19
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多