Library / Drag, swipe & scroll
Swipe action arming (swipe to archive)
Swiping a row until the action arms ("release to archive") — a tick when it arms and when it disarms.
import SwiftUI
struct SwipeableRow: View {
let title: String
let onArchive: () -> Void
@State private var offsetX: CGFloat = 0
@State private var armed = false
private let commitPoint: CGFloat = -96
private let tick = UISelectionFeedbackGenerator()
var body: some View {
ZStack(alignment: .trailing) {
Color.orange
Label("Archive", systemImage: "archivebox")
.foregroundStyle(.white).padding(.trailing, 24)
Text(title)
.frame(maxWidth: .infinity, alignment: .leading)
.padding().background(.background)
.offset(x: offsetX)
.gesture(
DragGesture()
.onChanged { value in
offsetX = min(0, value.translation.width)
let nowArmed = offsetX < commitPoint
if nowArmed != armed {
armed = nowArmed
tick.selectionChanged() // arm & disarm
}
}
.onEnded { _ in
if armed { onArchive() }
withAnimation(.spring) { offsetX = 0; armed = false }
}
)
}
.clipShape(RoundedRectangle(cornerRadius: 12))
.frame(height: 56)
}
}