Expandable cell in List View shows slowly after swiping to delete it

If the cell is expandable in List View, it will show slowly after deletion swipe.

the image shows how it looks like when this issue happens and it should be easy to reproduce with this sample codes


// Model for list items
struct ListItem: Identifiable {
    let id = UUID()
    let title: String
    let createdDate: Date
    let description: String
}

struct ExpandableListView: View {
    // Sample constant data
    private let items: [ListItem] = [
        ListItem(
            title: "First Item",
            createdDate: Date().addingTimeInterval(-86400 * 5),
            description: "This is a detailed description for the first item. It contains two lines of text to show when expanded."
        ),
        ListItem(
            title: "Second Item",
            createdDate: Date().addingTimeInterval(-86400 * 3),
            description: "This is a detailed description for the second item. It provides additional information about this entry."
        ),
        ListItem(
            title: "Third Item",
            createdDate: Date().addingTimeInterval(-86400 * 1),
            description: "This is a detailed description for the third item. Tap to expand and see more details here."
        ),
        ListItem(
            title: "Fourth Item",
            createdDate: Date(),
            description: "This is a detailed description for the fourth item. It shows comprehensive information when tapped."
        )
    ]

    // Track which item is currently selected/expanded
    @State private var selectedItemId: UUID? = nil

    var body: some View {
        NavigationView {
            List {
                ForEach(items) { item in
                    ExpandableCell(
                        item: item,
                        isExpanded: selectedItemId == item.id
                    ) {
                        // Handle tap - toggle selection
                        withAnimation(.easeInOut(duration: 0.3)) {
                            if selectedItemId == item.id {
                                selectedItemId = nil
                            } else {
                                selectedItemId = item.id
                            }
                        }
                    }
                }
                .onDelete { indexSet in
                    for index in indexSet {
                        print("delete \(items[index].title)")
                    }
                }
            }
            .navigationTitle("Items")
        }
    }
}

struct ExpandableCell: View {
    let item: ListItem
    let isExpanded: Bool
    let onTap: () -> Void

    private var dateFormatter: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        formatter.timeStyle = .short
        return formatter
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            // Always visible: Title and Date
            HStack {
                VStack(alignment: .leading, spacing: 4) {
                    Text(item.title)
                        .font(.headline)
                        .foregroundColor(.primary)

                    Text(dateFormatter.string(from: item.createdDate))
                        .font(.caption)
                        .foregroundColor(.secondary)
                }

                Spacer()

                // Chevron indicator
                Image(systemName: isExpanded ? "chevron.up" : "chevron.down")
                    .foregroundColor(.secondary)
                    .font(.caption)
            }

            // Expandable: Description (2 lines)
            if isExpanded {
                Text(item.description)
                    .font(.body)
                    .foregroundColor(.secondary)
                    .lineLimit(2)
                    .fixedSize(horizontal: false, vertical: true)
                    .transition(.opacity.combined(with: .move(edge: .top)))
                    .padding(.top, 4)
            }
        }
        .padding(.vertical, 8)
        .contentShape(Rectangle())
        .onTapGesture {
            onTap()
        }
    }
}

#Preview {
    ExpandableListView()
}

Detail flow to trigger this issue

  1. swipe on the cell to see the delete buttn
  2. cancel the swipe deletion
  3. tap the cell immediately
  4. the cell view will expand in broken animation

That's an odd behavior and could be a bug. Also NavigationView has been deprecated, please use NavigationStack instead.

For your use case have you tried using a DisclosureGroup instead? It should get you pretty close to what you have.

Please also submit a bug report, include the sample code and post the Feedback ID number here.

Would like to pile on with a mention of FB19602925 (filed back in mid-August): SwiftUI List: change to items animate incorrectly when swipeAction is involved. I think it could be the same issue.

Contains a minimal project to reproduce.

If UIDesignRequiresCompatibility is set to true, the problem goes away. Issue is tied to Liquid Glass.

Expandable cell in List View shows slowly after swiping to delete it
 
 
Q