Atoll/SHEET_PRESENTATION_FIX.md
Hariharan Mudaliar e77b6ab8cd Mostly Working
2025-10-11 16:09:46 +05:30

5.2 KiB

Sheet Presentation Fix

Problems Fixed

Issue 1: Editor Not Opening After App Restart ✅

Symptom: After restarting the app, clicking "Edit Animation" showed logs but editor sheet didn't appear.

Root Cause: The sheet was using .sheet(isPresented: $showingEditor) with an if let url = editorSourceURL wrapper inside. When state variables were updated, SwiftUI's sheet didn't properly re-evaluate the if let condition, causing the sheet content to be nil even though isPresented was true.

Fix: Changed to item-based sheet presentation:

// Before (BROKEN)
.sheet(isPresented: $showingEditor) {
    if let url = editorSourceURL {
        AnimationEditorView(...)
    }
}

// After (WORKING)
.sheet(item: Binding(
    get: { showingEditor ? EditorState(...) : nil },
    set: { newValue in showingEditor = (newValue != nil) }
)) { state in
    AnimationEditorView(...)
}

This ensures the sheet content is always evaluated when showingEditor changes.

Issue 2: Imports Not Showing Editor ✅

Symptom: When importing new animations, the editor didn't open, animations were imported with default transforms.

Root Cause: Same as Issue 1 - the sheet state wasn't being properly synchronized.

Fix: Added delays and logging:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    showingEditor = true
    print("📥 [Import] Opening editor for new import")
}

Issue 3: Edit Button Clicks Not Registering After Restart ✅

Symptom: Logs showed edit was being triggered, but sheet didn't appear.

Root Cause: State updates were happening synchronously, and SwiftUI sheet wasn't detecting the change.

Fix: Added small delay before setting showingEditor = true:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
    showingEditor = true
    print("🔧 [Edit] Sheet should now be visible")
}

Technical Details

EditorState Struct

Created a new identifiable struct to properly manage sheet state:

private struct EditorState: Identifiable {
    let id = UUID()
    let url: URL?
    let isRemote: Bool
    let existingAnimation: CustomIdleAnimation?
}

This makes the sheet's item parameter work correctly and ensures proper state management.

State Flow

  1. User clicks "Edit" or imports file
  2. State variables set: editorSourceURL, editorIsRemote, editingExistingAnimation
  3. After 0.05-0.1s delay: showingEditor = true
  4. Sheet's item getter evaluates and creates EditorState
  5. Sheet presents with correct AnimationEditorView
  6. On dismiss: Sheet's item setter cleans up state

Benefits of Item-Based Presentation

  • More reliable: Item changes always trigger sheet updates
  • Better cleanup: Setter can clean up state when sheet dismisses
  • Type safety: Editor state is encapsulated in a struct
  • Debugging: State changes are more explicit and trackable

Testing

Test 1: Edit After Restart

  1. Launch app
  2. Right-click any animation
  3. Click "Edit Animation"
  4. Check console:
    🔧 [Edit] Attempting to edit animation: Orange Cat Peeping
    🔧 [Edit] Animation source: lottieFile(...)
    🔧 [Edit] Lottie file URL: file://...
    🔧 [Edit] File exists: true
    🔧 [Edit] Sheet should now be visible
    
  5. Editor should open ✅

Test 2: Import New Animation

  1. Click "+" button
  2. Select a Lottie JSON file
  3. Check console:
    📥 [Import] Opening editor for new import
    
  4. Editor should open with preview and controls ✅
  5. Adjust transforms, save
  6. Animation should appear in grid with transforms applied ✅

Test 3: Import from URL

  1. Click "+" → "From URL"
  2. Enter URL and name
  3. Click "Import"
  4. Check console:
    📥 [Import] Opening editor for URL import
    
  5. Editor should open ✅

Test 4: Rapid Edits

  1. Edit an animation
  2. Save
  3. Immediately edit again
  4. Editor should open both times ✅

Console Logs to Watch For

Successful Edit Flow:

🔧 [Edit] Attempting to edit animation: [name]
🔧 [Edit] Animation source: [source type]
🔧 [Edit] Sheet should now be visible
✅ [AnimationEditor] Saved transform override for: [name]
📋 [CustomIdleAnimation] Found override for '[name]': AnimationTransformConfig(...)
🎨 [IdleAnimationView] Rendering animation: [name]

Successful Import Flow:

📥 [Import] Opening editor for new import
✅ [AnimationEditor] Imported animation: [name]
🎨 [IdleAnimationView] Rendering animation: [name]

If Issues Persist

  1. Check Console: Look for the "Sheet should now be visible" message
  2. Verify State: Add breakpoint in sheet's item getter to see if it's being called
  3. Check Delays: If sheet still doesn't open, increase delay to 0.2s
  4. Clean Build: Sometimes Xcode needs a clean build (Cmd+Shift+K)
  5. Check Logs: All state changes should be logged now

Architecture Benefits

The new item-based sheet presentation is more robust because:

  • ✅ SwiftUI always evaluates item changes
  • ✅ No nested if let inside sheet content
  • ✅ State cleanup happens automatically in setter
  • ✅ Better for async state updates
  • ✅ More predictable behavior after app restarts
  • ✅ Easier to debug with explicit state object