SwiftUI Form animation results in inconsistent view state

Viewed 121

When running the below example code in the canvas (Xcode 12.4) or on a device (iOS 14.5) I always end up in an inconsistent UI state if I quickly double click the Edit/Cancel button.

It should just insert or remove a Section in the Form, but whenever I activate animations it seems to insert the first section "too late":

Inconsistent Consistent

The first image is after a double click and does not reflect the view's state. More specifically the first section is out of sync with the rest of the UI; the first section should not exist. The second image is after a single click and looks as it should.

I get the same result when using withAnimation in the Buttons' action instead of .animation on the Form.

Minimal example:

import SwiftUI

struct TestView: View {
    
    enum Mode: String { case view, edit }
    
    @State private var mode: Mode = .view
        
    var modeString: String { "We're in \(mode.rawValue) mode" }
    var modeColor: Color { mode == .view ? .green : .red }
    var title: String { mode.rawValue + " mode" }
        
    var body: some View {
                
        let editButton = Button("Edit") { mode = .edit }
        let cancelButton = Button("Cancel") { mode = .view }
                
        NavigationView {
            Form {
                if mode == .edit {
                    Section(header: Text(modeString)) {
                        Text(modeString).foregroundColor(modeColor)
                    }
                }
                
                Section(header: Text(modeString)) {
                    Text(modeString).foregroundColor(modeColor)
                }
            }
            .navigationBarItems(trailing: mode == .view ? editButton : cancelButton)
            .navigationBarTitle(title)
            .animation(.default)
        }
    }
}

struct TestView_Previews: PreviewProvider {
    static var previews: some View {
            TestView()
    }
}

Did I do something wrong here?


Possibly related question: Animating a SwiftUI state change while existing animation is running causes Form to be in an inconsistent state

0 Answers
Related