commit 1c747f5cf8e2a14218deb788e9087c8267a85ac3
parent cfeed7a5f1aa2c64e5b8382009d5ab76eb3c9f6f
Author: Michael Camilleri <[email protected]>
Date: Wed, 1 Apr 2026 19:09:59 +0900
Try alternative fix for animation bug
The previous commit's fix didn't work. This approach takes advantage of
the `completion` argument to the `.withAnimation` modifier to reset the
status of a view so that if it is recycled by SwiftUI, it's back in its
reset state.
Co-Authored-By: Claude 4.6 Opus <[email protected]>
Diffstat:
4 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/ListlessiOS/Extensions/ItemListView+Undo.swift b/ListlessiOS/Extensions/ItemListView+Undo.swift
@@ -68,7 +68,6 @@ extension ItemListView {
} catch {
presentStoreError(error)
}
- iState.undoGeneration &+= 1
dismissUndoToast()
}
diff --git a/ListlessiOS/Helpers/ItemRowSwipeGesture.swift b/ListlessiOS/Helpers/ItemRowSwipeGesture.swift
@@ -149,10 +149,13 @@ struct ItemRowSwipeGesture: ViewModifier {
// ForEach re-evaluation animate it out of the active section.
triggerAction(action: onComplete)
} else {
- // Delete: slide off screen
+ // Delete: slide off screen, then reset so undo doesn't
+ // restore the row with a frozen swipe state.
triggerAction(action: onDelete)
withAnimation(.spring(response: 0.3, dampingFraction: 0.7)) {
swipeOffset = -400
+ } completion: {
+ resetSwipeState()
}
}
} else {
diff --git a/ListlessiOS/Views/ItemListView.swift b/ListlessiOS/Views/ItemListView.swift
@@ -23,7 +23,6 @@ struct ItemListView: View, ItemListViewProtocol {
var draftPlacement: DraftItemPlacement?
var draftTitle: String = ""
var fetchWorkaround: Int = 0
- var undoGeneration: Int = 0
var isShowingOverlay: Bool {
isShowingSettings || isShowingSyncDiagnostics || isShowingRenameAlert
diff --git a/ListlessiOS/Views/ItemRowView.swift b/ListlessiOS/Views/ItemRowView.swift
@@ -15,7 +15,6 @@ struct ItemRowView: View {
let isLastActiveItem: Bool
let onStartEdit: (UUID) -> Void
let onEndEdit: (UUID, _ shouldCreateNewItem: Bool) -> Void
- let undoGeneration: Int
@FocusState.Binding var focusedField: FocusField?
@AppStorage("colorTheme") private var colorThemeRaw = 0
@@ -37,7 +36,6 @@ struct ItemRowView: View {
isDragging: Binding<Bool> = .constant(false),
isSwiping: Binding<Bool> = .constant(false),
isLastActiveItem: Bool = false,
- undoGeneration: Int = 0,
focusedField: FocusState<FocusField?>.Binding,
onToggle: @escaping (UUID) -> Void,
onTitleChange: @escaping (UUID, String) -> Void,
@@ -54,7 +52,6 @@ struct ItemRowView: View {
_isDragging = isDragging
_isSwiping = isSwiping
self.isLastActiveItem = isLastActiveItem
- self.undoGeneration = undoGeneration
self.onToggle = onToggle
self.onTitleChange = onTitleChange
self.onDelete = onDelete
@@ -176,15 +173,6 @@ struct ItemRowView: View {
.onChange(of: colorThemeRaw) { _, _ in
cachedAccentColor = computeAccentColor()
}
- .onChange(of: undoGeneration) { _, _ in
- var transaction = Transaction(animation: nil)
- transaction.disablesAnimations = true
- withTransaction(transaction) {
- swipeOffset = 0
- swipeDirection = .none
- isSwipeTriggered = false
- }
- }
.itemSwipeGesture(
isDragging: $isDragging,
isEditing: focusedField == .item(itemID),