Imagine que você tem um struct
like
struct TheObject: Identifiable, Hashable {
var id: String
var title: String
}
Agora você armazena um array desse tipo dentro de um ViewModel
class Model: ObservableObject {
@Published var objects = [TheObject(id: "id", title: "title")]
}
Você cria um NavigationLink
para cada item de objects
. Esses NavigationLinks apresentam um botão, que substitui o objects
array pelo mesmo objeto (por id), mas uma propriedade diferente
@StateObject var model = Model()
NavigationStack {
List(model.objects) { object in
NavigationLink("Text", value: object)
}
.navigationDestination(for: TheObject.self) { object in
Text(object.title)
.onTapGesture {
model.objects = [TheObject(id: "id", title: "title changed")]
}
}
}
O que eu esperava que acontecesse?
Eu esperava que meu NavigationLink aberto fosse atualizado com o novo título.
O que eu ganhei em vez disso?
A visão não mudou. Em vez disso, tenho que abrir a visualização e reabri-la para revelar as alterações.
Como posso fazer com que meu comportamento esperado funcione e por que ele se comporta assim atualmente?
Quando você usa
Text(object.title)
o passadoobject
é umlet
e não é observado alterações pela view, portanto não mudará quando você alterar o modelo noonTapGesture
.Mas a visualização mudará se você usar o modelo (que é observado para alterações), conforme mostrado no código de exemplo.
EDITAR-1:
Uma alternativa para conseguir o que deseja é usar o
Observable
, o substituto mais robusto doObservableObject class
.Por exemplo:
O motivo pelo qual sua Visualização de Texto não está sendo atualizada é que ela
object
é passada para o encerramento como uma cópia, não é a mesma instância demodel
. Para exibir o valor mutado, você teria que passar a mesma instância paramodel
a Visualização de Texto da seguinte forma: