← All repositories

listless

A simple list app for Apple platforms

git clone https://code.inqk.net/listless.git


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

MListlessiOS/Extensions/ItemListView+Undo.swift | 1-
MListlessiOS/Helpers/ItemRowSwipeGesture.swift | 5++++-
MListlessiOS/Views/ItemListView.swift | 1-
MListlessiOS/Views/ItemRowView.swift | 12------------

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),