SwiftUI实现仿备忘录App带确认弹窗的删除功能及按钮宽度问题
SwiftUI实现备忘录风格删除交互:解决删除按钮无法铺满单元格宽度问题
问题描述
尝试在SwiftUI中实现苹果备忘录(Notes)App的删除笔记交互逻辑,当前代码已实现侧滑删除按钮,但存在删除按钮无法铺满单元格宽度的问题,效果如下:

当前代码:
import SwiftUI struct ItemStore { var items: [String] } struct ContentView: View { let itemStore = ItemStore(items: [ "Hi", "Hello" ]) @State var showingAlert = false var body: some View { List { ForEach(itemStore.items, id: \.self) { item in Text("Item: \(item)") .swipeActions() { Button { withAnimation { showingAlert.toggle() } } label: { Label("Delete", systemImage: "trash") } } .tint(.red) } } .alert("Important message", isPresented: $showingAlert) { Button("First") { } Button("Second") { } } } }
解决方案
要实现类似备忘录的全屏侧滑删除按钮,需做两个关键修改:
- 使用
.fullSwipeAction替代普通的.swipeActions,这是SwiftUI专门用于实现全屏侧滑触发的动作API - 修正数据可变性,确保能实际删除列表项;同时为每个列表项绑定对应删除确认逻辑
修改后的完整代码:
import SwiftUI struct ItemStore { var items: [String] } struct ContentView: View { // 将itemStore改为@State,允许修改列表数据 @State private var itemStore = ItemStore(items: [ "Hi", "Hello" ]) // 用可选值存储当前要删除的item,避免多个item共用同一个alert状态 @State private var itemToDelete: String? var body: some View { List { ForEach(itemStore.items, id: \.self) { item in Text("Item: \(item)") // 使用fullSwipeAction实现全屏侧滑删除 .fullSwipeAction(edge: .trailing) { // 触发删除确认弹窗 itemToDelete = item } label: { Label("Delete", systemImage: "trash") } .tint(.red) } } // 绑定到当前要删除的item,只有当itemToDelete不为空时才显示弹窗 .alert("确定要删除这条笔记吗?", isPresented: $itemToDelete.isPresent()) { Button("取消", role: .cancel) { itemToDelete = nil } Button("删除", role: .destructive) { if let item = itemToDelete { // 执行删除操作 itemStore.items.removeAll { $0 == item } itemToDelete = nil } } } } } // 扩展Optional,方便绑定alert的isPresented extension Optional { func isPresent() -> Binding<Bool> { Binding( get: { self != nil }, set: { if !$0 { self = nil } } ) } }
代码说明
.fullSwipeAction(edge: .trailing):该API会创建铺满单元格宽度的侧滑动作按钮,完全匹配备忘录App的交互效果- 将
itemStore改为@State:原let常量无法修改数据,改为@State后可实时更新列表内容 - 使用
itemToDelete可选值:避免所有列表项共用同一个showingAlert状态,确保弹窗只对应当前要删除的项 - 自定义
isPresent()绑定:简化可选值到Bool的转换,让alert显示逻辑更清晰
内容的提问来源于stack exchange,提问作者Javier Roberto
相关产品推荐
相关产品推荐

