🔄 Keep meal UI state in sync during background updates (checkboxes, chevrons, expand/collapse)
What we're fixing:
When you interact with meals throughout the day (checking off items, expanding/collapsing sections), the app syncs your data in the background with the cloud. During this sync process, multiple UI state issues can occur: nutrient totals at the top don't always update, chevron arrows can point the wrong direction, and meal sections can unexpectedly expand or collapse. This task ensures that all meal UI elements—checkboxes, chevrons, expanded/collapsed states, and nutrient totals—stay properly synchronized even when background syncing is happening.
Overview
We have three related issues that occur when interacting with meals while a sync is happening. These manifest as UI state getting out of sync with the underlying data model.
Issue 1: Nutrient amounts in expandable header not updating after sync ✅ PARTIALLY FIXED
Problem: When toggling logged states during a sync, the nutrient totals in the expandable day header at the top don't recalculate to match what's currently checked off when sync completes.
Fix Applied:
- ●Added
updateCircleState()call inDayViewController.updateVisibleCellsAnimated()at line 1405 to ensure logged state checkmarks update after sync - ●The expandable header already has proper logic to show consumed values via
day.consumedValue(for:)when in log mode
Files Modified:
- ●
/Users/pxlshpr/Developer/NutriKit/DayViewController.swift:1404-1407- Added updateCircleState() call
Issue 2: Meal header chevrons getting out of sync ⚠️ NEEDS DIAGNOSIS
Problem: The collapse/expand chevrons on meal headers can get out of sync with the actual collapse state, especially during rapid tapping.
Symptoms:
- ●Takes 3 taps to actually turn the chevron
- ●Chevron never turns with expand/collapse toggles
- ●Chevron points wrong direction after rapid tapping
Attempted Fixes (Reverted):
- ●Tried updating chevron rotation in
updateValues()- caused chevron to always revert to pointing down - ●Tried debounced self-check after rapid tapping - still exhibited wrong behavior
Current State: Reverted to simple original approach and added comprehensive diagnostic logging to identify the root cause.
Diagnostic Logging Added in MealHeaderTableViewCell.swift:
- ●📍 CONFIGURE logs (lines 559-564) - initial state setup
- ●🔄 UPDATE_VALUES logs (lines 663-684) - state comparison during updates
- ●⚠️ STATE MISMATCH DETECTED logs - when cell detects desync
- ●Existing tap/toggle logs already in place
Files Modified:
- ●
/Users/pxlshpr/Developer/NutriKit/MealHeaderTableViewCell.swift:559-564, 663-684- Added diagnostic logging
Related Code Locations:
- ●Chevron tap handler:
MealHeaderTableViewCell.swift:1544 - ●Collapse state logic:
MealHeaderTableViewCell.swift:659-684 - ●Configure chevron:
MealHeaderTableViewCell.swift:548-564
Issue 3: Meal expanded/collapsed state desyncing during background updates ⚠️ NEW
Problem: The actual expanded/collapsed state of meal sections can get out of sync during background CloudKit sync operations. This is related to but distinct from Issue 2 - Issue 2 is about the chevron icon rotation, while this is about the actual meal section state.
Requirements:
- ●State Verification During Sync:
- ●Check and verify the expanded/collapsed state of all meal sections during and after sync operations
- ●Ensure meal sections maintain their intended state even when data updates occur
- ●Prevent sync operations from inadvertently expanding or collapsing meal sections
- ●Icon Rotation Synchronization:
- ●Ensure chevron icon rotation always matches the actual expanded/collapsed state
- ●Fix any desync between visual indicator (chevron) and actual state (section expanded/collapsed)
- ●Handle state changes that occur during sync operations
- ●Alternative Rotation Approach (Consider):
Instead of applying rotation modifiers to a single chevron image, consider:
- ●Using two separate, pre-rotated image elements (one for each state)
- ●Hot-swapping between the images based on expanded/collapsed state
- ●This avoids animation/rotation timing issues and ensures the icon always shows the correct orientation
- ●Implementation: Place both images in the view, but only show one at a time based on state
Benefits of Hot-Swap Approach:
- ●Eliminates rotation animation timing issues
- ●No need to track rotation state separately from expanded/collapsed state
- ●Simpler state management - one source of truth
- ●Avoids edge cases where rotation animation gets interrupted
Next Steps
For Issue 2 & 3:
- ●
Test rapid tapping on meal headers while monitoring logs:
log stream --predicate 'message CONTAINS "[MealHeader]"' --level debug - ●
Analyze logs to identify where chevron state and meal state get out of sync
- ●
Test during sync operations:
- ●Trigger background sync while expanding/collapsing meals
- ●Monitor both chevron rotation and actual section state
- ●Identify if sync operations cause state changes
- ●
Determine root cause - likely one of:
- ●Timing issue (animation vs state update)
- ●State management problem (cell reuse or model updates)
- ●Table reload interference (cell getting reconfigured mid-animation)
- ●Sync-triggered data updates causing unintended UI state changes
- ●
Consider implementing hot-swap approach for chevron rotation to eliminate rotation-related issues
- ●
Implement targeted fix based on diagnostic findings
Technical Context
Component: Meal logging diary view with expandable/collapsible meal sections Framework: UIKit (UITableView with custom cells) State Management: Day model with meal items, CloudKit sync in background Animation: Chevron rotation animations tied to expand/collapse state
Why This Matters: This affects the core logging functionality where users check off meals throughout the day. UI state desyncs during CloudKit sync operations create confusion and poor UX, especially for users actively logging while syncing.
Acceptance Criteria
- ● Nutrient totals in expandable header update correctly after sync completes (Issue 1)
- ● Chevron rotation matches actual expand/collapse state of meal headers (Issue 2)
- ● Rapid tapping on meal headers doesn't cause chevron state desync (Issue 2)
- ● Meal expanded/collapsed state remains correct during and after background sync operations (Issue 3)
- ● Chevron icon rotation stays in sync with meal state even when state changes during sync (Issue 3)
- ● Consider and evaluate hot-swap image approach vs rotation modifier approach (Issue 3)
- ● All diagnostic logs removed or converted to appropriate log level after fix
- ● No regressions in meal header expand/collapse behavior
Build instruction: Use -destination 'platform=iOS Simulator,name=iPhone 17 Pro' when building this project