SwiftUI List row expansion causes weird bounce effect

When using a List in SwiftUI, expanding row items using anything other than the default DisclosureGroupStyle seems to cause a "bounce" during expansion/collapse.

What is the recommended way to avoid this bounce?

Link to code: https://github.com/dannys42-bugs/BugListExpansion (includes a small video demonstrating the issue)

Answered by DTS Engineer in 799829022

@dannys42 This is not a bug. DisclosureGroup is a default built-in disclosure control provided by SwiftUI.

Depending on the context it's used whether it being within a List, a Stack, or side could behave and animate differently.

In your custom disclosure group style, create a Transaction and set animation = nil to disable the animation.

For example:

struct MyDisclosureStyle: DisclosureGroupStyle {
    func makeBody(configuration: Configuration) -> some View {
        VStack {
            Button {
                var transition = Transaction(animation: .snappy)
                transition.animation = nil
                withTransaction(transition) {
                    configuration.isExpanded.toggle()
                }
            } label: {
                HStack(alignment: .firstTextBaseline) {
                    configuration.label
                    Spacer()
                    Text(configuration.isExpanded ? "hide" : "show")
                        .animation(nil, value: configuration.isExpanded)
                }
                .contentShape(Rectangle())
            }
            .buttonStyle(.plain)
            if configuration.isExpanded {
                configuration.content
            }
        }
    }
}

@dannys42 This is not a bug. DisclosureGroup is a default built-in disclosure control provided by SwiftUI.

Depending on the context it's used whether it being within a List, a Stack, or side could behave and animate differently.

In your custom disclosure group style, create a Transaction and set animation = nil to disable the animation.

For example:

struct MyDisclosureStyle: DisclosureGroupStyle {
    func makeBody(configuration: Configuration) -> some View {
        VStack {
            Button {
                var transition = Transaction(animation: .snappy)
                transition.animation = nil
                withTransaction(transition) {
                    configuration.isExpanded.toggle()
                }
            } label: {
                HStack(alignment: .firstTextBaseline) {
                    configuration.label
                    Spacer()
                    Text(configuration.isExpanded ? "hide" : "show")
                        .animation(nil, value: configuration.isExpanded)
                }
                .contentShape(Rectangle())
            }
            .buttonStyle(.plain)
            if configuration.isExpanded {
                configuration.content
            }
        }
    }
}

Thanks @DTS Engineer for your reply. Unfortunately doing it that way results in no smooth animation -- the expansion simply "pops" rather than smoothly expanding. Also in my actual app, I have other animations I'm trying to trigger (e.g. fadein/out effects depending on the expansion state) that I believe this would negate? I suppose I could have a separate state for that. But it still allow the list row to smoothly expand/collapse like the default DisclosureGroupStyle.

Is there no way to achieve behavior that is similar to the default? I'd consider a VStack, but then I lose the ability handle move/delete operations easily.

SwiftUI List row expansion causes weird bounce effect
 
 
Q