Antigamente, quando você precisava controlar algo que está profundamente na hierarquia de visualização, você poderia simplesmente usar
NotificationCenter.default.addObserver
e, em seguida, poste notificações em seus objetos e eles serão alterados.
Agora com o SwiftUI, se você tiver apenas um nível de visualizações, você pode simplesmente passar a @State
variável para a próxima visualização, que então fará uma ligação a ela.
Mas imagine uma visualização com 4 visualizações de profundidade.
View A > View B > View C > View D
Não acho que seria elegante passar a @State
variável com 4 níveis de profundidade, então View D
posso alterá-la.
Outra maneira feia seria criar um @Observable
singleton com uma @Published
variável.
Qual é a prática comum para fazer isso?
SwiftUI possui um sistema de ambiente projetado para essa finalidade. Os valores são declarados em um ponto na hierarquia de visualizações do SwiftUI - geralmente, mas nem sempre, no topo - e são automaticamente compartilhados com todas as visualizações filhas daquela visualização, todas as suas visualizações filhas e assim por diante. As visualizações que precisam usar esses dados optam por fazê-lo.
Cada dado no ambiente possui uma chave distinta para definir o valor no topo e recuperá-lo quando necessário.
Existem três tipos de uso:
Para tipos de valor (estruturas, enums, tipos integrados como
Int
eString
), você pode criar customizaçõesEnvironmentValues
que usam um caminho-chave para identificar o valor.Contexto:
Usando:
Criar uma chave de ambiente personalizada requer um pouco de código padrão, mas é praticamente o mesmo sempre. Esta é apenas uma postagem de blog com exemplos e há muitos mais.
Para tipos de referência (classes), a maneira mais antiga é fazer com que sua classe esteja em conformidade com o
ObservableObject
. O tipo da sua classe se torna a chave:Novidade no iOS 17+ , há uma sintaxe alternativa usando a nova
@Observable
macro que eliminaObservableObject
ePublished
: