7.8 C
New York
Sunday, March 16, 2025

ios – SwiftUI NavigationLink Unexpectedly Pops When Modifying State


Subject
I’m encountering a difficulty in SwiftUI the place modifying a value-type mannequin inside a baby view typically causes the navigation stack to pop unexpectedly. This occurs though I am solely modifying a property contained in the youngster view, not changing the whole mannequin.

Context
I’ve an inventory of things in a NavigationStack, the place choosing an merchandise navigates to a element view. The element view permits enhancing the title property through a TextField.

Right here’s the simplified code:

import SwiftUI

struct Merchandise: Identifiable, Hashable {
    let id: UUID
    var title: String
}

struct ContentView: View {
    @State non-public var objects = [
        Item(id: UUID(), name: "Item 1"),
        Item(id: UUID(), name: "Item 2")
    ]

    var physique: some View {
        NavigationStack {
            Listing($objects) { $merchandise in
                NavigationLink(merchandise.title, worth: merchandise)
            }
            .navigationDestination(for: Merchandise.self) { merchandise in
                DetailView(merchandise: merchandise)
            }
        }
    }
}

struct DetailView: View {
    @State var merchandise: Merchandise  // <- Native copy of the merchandise

    var physique: some View {
        VStack {
            TextField("Edit Title", textual content: $merchandise.title)
                .textFieldStyle(.roundedBorder)
                .padding()
        }
        .navigationTitle(merchandise.title)
    }
}

Drawback

Once I sort within the TextField, the view typically pops again to the earlier display with out urgent the again button. It looks like the navigation stack is shedding monitor of my Merchandise occasion when its title is up to date.

  1. Used @Binding in DetailView
  • Modified DetailView to just accept a @Binding var merchandise: Merchandise as a substitute of utilizing @State.
  • This prompted a compiler error as a result of NavigationDestination passes a copied worth, not a binding.
  1. Wrapped Merchandise in a Reference Kind (class)
  • Transformed Merchandise from a struct to a category and used @ObservableObject.
  • This fastened the navigation pop subject however launched issues with Codable, Hashable, and thread security.
  1. Tracked the Chosen Merchandise Individually
  • Launched an express @State non-public var selectedItem: Merchandise? in ContentView.

  • Manually assigned the chosen merchandise earlier than navigation.

  • This labored however felt like a hack moderately than a SwiftUI-friendly strategy.

  • Anticipated Habits
    Updating merchandise.title inside DetailView ought to solely replace that subject and never trigger SwiftUI to pop the navigation stack.

  • Precise Habits
    Altering merchandise.title typically causes the view to pop unexpectedly, as if SwiftUI misplaced monitor of the navigation state.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles