A maioria dos modificadores SwiftUI modificam as visualizações abaixo deles na hierarquia, mas alguns modificadores modificam as visualizações acima deles na hierarquia. No meu exemplo abaixo .navigationTitle
, .toolbar
, e .presentationDetents
estão modificando elementos da pilha de navegação e da planilha em que são apresentados, mas são instalados em uma visualização de texto.
Conceitualmente, como esses modificadores funcionam internamente? Mais ainda, como eu poderia criar um meu?
Estou criando minha própria pilha de navegação (por razões irrelevantes) e tenho uma abordagem que parece promissora, mas tenho dúvidas sobre ela. Minha abordagem atual é um modificador de visualização que define propriedades em um objeto de ambiente, e o objeto de ambiente é um modelo de visualização para a pilha de navegação personalizada.
Os valores de preferência passam dados para cima na hierarquia de exibição, de forma semelhante à forma como os valores de ambiente passam dados para baixo na hierarquia de exibição.
Os valores de preferência podem ser definidos usando
preference
, ou modificados usandotransformPreference
. Esses valores podem ser lidos poronPreferenceChange
, oubackgroundPreferenceValue
ouoverlayPreferenceValue
se você quiser adicionar um plano de fundo/sobreposição com base em um valor de preferência.Aqui está um exemplo simples para demonstrar que os valores de preferência podem ser lidos na visualização pai:
Observe o
reduce
método na chave de preferência. Esse método é usado para combinar valores de preferência de visualizações irmãs, já que a pai deve receber um valor mesmo se suas subvisualizações tiverem valores de preferência diferentes definidos. No exemplo acima, a sobreposição mostra "5".Uma invariante importante que a implementação deve satisfazer é que
defaultValue
deve ser uma identidade dereduce
-reduce(value: &x, nextValue: {defaultValue})
não deve mudarx
.navigationTitle
usatransformPreference
para definir algum valor de preferência representando alguma configuração da barra de ferramentas. Você pode dar uma olhada nos detalhes internos do SwiftUI imprimindoIsto imprime:
_PreferenceTransformModifier
é o modificador de visualização quetransformPreference
se aplica e, neste caso, está transformando alguma chave de preferência chamadaToolbarKey
.toolbar
epresentationDetents
são mais opacos em como funcionam e podem não ser implementados usando um valor de preferência.Há também
ContainerValues
. Diferentemente dos valores de preferência que enviam dados para cima na hierarquia de visualização o mais longe possível (semelhante a como os valores de ambiente são enviados o mais para baixo possível), os valores de contêiner são enviados apenas um nível acima, e o pai pode ler os valores de contêiner de cada subvisualização individual. Isso é semelhante a comotag
funciona.Para completar, aqui está uma demonstração: