SwiftUI sheet with TextField using autocorrectionDisabled() prevents view model deinit after editing

I present a view as a sheet that contains a TextField and a viewModel. The sheet uses .autocorrectionDisabled() on the TextField.

If I open the sheet and dismiss it without editing, the viewModel is released as expected. But if I edit the TextField and then dismiss the sheet, the viewModel is not deinitialized (it remains retained).

Test Outputs:

// # Present 1st time - Correct ✅
TestViewModel - init - 0x0000600000c12ee0
// Dismiss wihtout editing, deinitialized correctly
TestViewModel - deinit - 0x0000600000c12ee0

// # Present 2st time - Incorrect ❌
TestViewModel - init - 0x0000600000c006c0
// Edit and dismiss, no deinit here

// # Present 3rd time - Incorrect ❌
TestViewModel - init - 0x0000600000c113b0
// Enter text field to edit will deinit previous one
TestViewModel - deinit - 0x0000600000c006c0
// Dismiss, no deinit
// TestViewModel (0x0000600000c113b0) remains retained ⚠️

Using .autocorrectionDisabled(true) gives the same problem. Removing or commenting out .autocorrectionDisabled() fixes the issue, but I don't want autocorrection enabled.

Is this a known SwiftUI bug? Has anyone encountered it and found a workaround?


Sample code:

@main
struct TestApp: App {

  @State private var isPresentingSheet: Bool = false

  var body: some Scene {
    WindowGroup {
      VStack {
        Button("Present Sheet") {
          self.isPresentingSheet = true
        }
      }
      .sheet(isPresented: $isPresentingSheet) {
        TestTextInputView()
      }
    }
  }
}

View (check the HERE line):

struct TestTextInputView: View {

  @StateObject private var viewModel = TestTextInputViewModel()
  @FocusState private var isFocused: Bool

  @Environment(\.dismiss) private var dismiss

  var body: some View {
    NavigationStack {
      Form {
        TextField("Name", text: $viewModel.name)
          .autocorrectionDisabled() // HERE: Comment it out will work without any issue.
          .focused($isFocused)
          .submitLabel(.done)
          .onSubmit {
            self.isFocused = false
          }
      }
      .toolbar {
        ToolbarItem(placement: .topBarLeading) {
          Button("Cancel") { dismiss() }
        }
      }
    }
  }
}

View Model:

final class TestTextInputViewModel: ObservableObject {

  @Published var name: String = ""

  deinit {
    print("TestViewModel - deinit - \(Unmanaged.passUnretained(self).toOpaque())")
  }

  init() {
    print("TestViewModel - init - \(Unmanaged.passUnretained(self).toOpaque())")
  }
}

My another concern is that the entire underlying UIView/UIViewController - not just the TestViewModel - is being retained in this case, and we can't tell instantly.

SwiftUI sheet with TextField using autocorrectionDisabled() prevents view model deinit after editing
 
 
Q