
[ad_1]
NavigationView e NavigationLink: navegação básica no SwiftUI
Antes da NavigationStack
e NavigationSplitView
SwiftUI introduziu o NavigationView
e NavigationLink
estruturas. Essas duas partes trabalham juntas para permitir a navegação entre as visualizações em seu aplicativo. o NavigationView
é usado para agrupar o conteúdo de suas visualizações, configurando-as para navegação subsequente. o NavigationLink
faz o trabalho real de atribuir qual conteúdo navegar e fornecer um componente de interface do usuário para o usuário iniciar essa navegação. Vejamos um exemplo rápido.
var body: some View { /// 1 NavigationView { Text("Primary View") NavigationLink( /// 2 destination: Text("Secondary View"), /// 3 label: { Text("Navigate") }) } }
Vamos dividir o acima:
- Englobamos nosso conteúdo dentro de um
NavigationView
caso contrário nossoNavigationLink
não funcionará. - Dentro do nosso
NavigationLink
nós atribuímos odestination
. Este é o conteúdo para o qual queremos navegar. - Atribui uma parte do conteúdo para atuar como um botão para a navegação.
Existem várias maneiras de configurar seu NavigationLink
, portanto, verifique a documentação para obter o sabor correto para sua própria implementação. O exemplo acima é apenas uma das maneiras mais simples de lidar com a navegação básica.
A coisa mais notável sobre isso em comparação com a forma como a navegação foi tratada anteriormente no UIKit é que todo o nosso código é tratado em um único local, dentro da própria visualização SwiftUI. Isso significa que teremos um código mais limpo em muitos casos, mas também que qualquer informação que queiramos passar para as telas subsequentes deve estar disponível na visualização da qual estamos navegando. Isso pode parecer uma distinção menor, mas será importante mais tarde.
NavigationStack e NavigationSplitView: novo no SwiftUI 4
NavigationStack
NavigationStack cria uma lista de exibições sobre uma exibição raiz em vez de definir cada exibição individualmente. Quando um usuário interage com um NavigationLink, uma visualização é adicionada ao topo da pilha. A pilha sempre mostrará a visualização adicionada mais recentemente que não foi removida.
Para criar um NavigationStack
:
var body: some View { NavigationStack { List(users) { user in NavigationLink(user.name, value: user) } .navigationDestination(for: User.self) { user in UserDetails(user: user) } } }
NavigationSplitView
é um tipo especial de visualização que se apresenta em duas ou três colunas — particularmente útil para tablets. As seleções na coluna principal (como um menu) controlarão a apresentação nas colunas seguintes (como uma caixa de conteúdo).
Para criar um NavigationSplitView
:
var body: some View { NavigationSplitView { List(model.users, selection: $userids) { user in Text(user.name) } } detail: { UserDetails(for: userids) } }
Um desenvolvedor pode incorporar um NavigationStack
dentro de um NavigationSplitView
coluna. Quando visualizado em um dispositivo de formato pequeno, as colunas serão recolhidas.
Ambos NavigationStack
e NavigationSplitView
são recém-introduzidos, mas ainda utilizam NavigationLink
. A Apple fornece instruções de migração para fazer a transição de tipos de navegação mais antigos para esses tipos de navegação mais recentes.
Navegação programática no SwiftUI
O que acontece quando preciso aguardar uma resposta de uma chamada de API antes de navegar? Que tal esperar a finalização de uma animação? Digamos que eu precise realizar a validação nos campos do usuário antes de navegar? E ENTÃO!?!?!? Bem, ao configurar seu NavigationLink
você faz isso com um isActive
parâmetro que permitirá alternar a navegação. Vamos conferir um exemplo rápido.
/// 1 @State var goWhenTrue: Bool = false var body: some View { NavigationView { Text("Primary View") /// 2 NavigationLink("Navigator", destination: Text("Subsequent View"), isActive: $goWhenTrue) } Button("Go Now") { /// 3 goWhenTrue = true }
- Precisamos de alguma variável para agir, e essa variável deve ser vinculável (@Binding, @State, etc) para que a exibição seja renderizada novamente e navegar quando for atualizada.
- Aqui montamos o
NavigationLink
. O primeiro parâmetro é uma tag para o próprio link e não é exibido na interface do usuário. oisActive
parâmetro é um booleano que controla se a navegação é executada. - Aqui definimos a variável de estado para
true
acionando assim a navegação em (2)
Isso pode ser configurado de várias maneiras diferentes, como a variável que está sendo controlada pela visão, um modelo de visão, um singleton ou qualquer outro ponto de referência dentro do aplicativo que a visão possa referenciar para o isActive
variável de ligação. Isso significa que não podemos esperar por outros critérios ou conclusões antes da navegação, mas isso realmente resolve todos os nossos problemas?
Navegação programática fora das visualizações
Mencionei acima que toda a navegação deve ser configurada dentro da visualização SwiftUI para que a navegação seja possível. Podemos acionar essa navegação de outros lugares usando as etapas descritas acima, mas e se nossa navegação for solicitada de fora da hierarquia de visualizações? Este pode ser o caso do Deep Linking, respondendo a um evento assíncrono ou qualquer outro motivo (use sua imaginação). Infelizmente, não há uma boa resposta para isso, mas no interesse da busca acadêmica, vamos ver o que podemos fazer! Abaixo está uma possível solução alternativa para esse problema. Vamos começar com o nosso NavigationCoordinator
que armazena nosso conteúdo antes de realizarmos a navegação.
class NavigationCoordinator: ObservableObject { /// 1 fileprivate var screen: AnyView = AnyView(EmptyView()) ///2 @Published fileprivate var shouldNavigate: Bool = false ///3 func show<V: View>(_ view: V) { let wrapped = AnyView(view) screen = wrapped shouldNavigate = true } }
- Isso armazena o conteúdo para o qual queremos navegar.
- Nossa variável de ligação para determinar quando queremos navegar.
- Um método auxiliar que lida com o encapsulamento de nosso conteúdo e inicia a navegação automaticamente quando atribuído.
A seguir, veremos nosso NavigationWrapper
que é implementado em qualquer visualização SwiftUI da qual queremos navegar.
struct NavigationWrapper<Content>: View where Content: View { /// 1 @EnvironmentObject var coordinator: NavigationCoordinator /// 2 private let content: Content public init(@ViewBuilder content: () -> Content) { self.content = content() } var body: some View { NavigationView { /// 3 if coordinator.shouldNavigate { NavigationLink( destination: coordinator.screen, isActive: $coordinator.shouldNavigate, label: { content }) } else { content } } /// 4 .onDisappear(perform: { coordinator.shouldNavigate = false }) } }
- É aqui que armazenamos as informações do nosso coordenador para uso posterior durante a navegação.
- É aqui que armazenamos o conteúdo que será exibido na visualização da qual estamos navegando. Este é essencialmente o seu corpo de visualização.
- Aqui verificamos se o coordenador deve navegar. Isso será verificado sempre que o objeto de ambiente for atualizado e acionará a navegação quando as coisas forem configuradas corretamente.
- Depois de navegarmos com sucesso para fora dessa visualização, queremos definir
shouldNavigate
para false para evitar que a próxima exibição na hierarquia tente navegar também no carregamento.
Isso foi projetado com a intenção de que você possa usar as implementações acima para permitir a navegação de qualquer lugar dentro de seu aplicativo para uma nova visualização, mesmo fora de uma visualização SwiftUI. É um pouco pesado, pois requer que qualquer cena que você implemente envolva seu conteúdo no NavigationWrapper
e passar as informações de coordenador apropriadas para ele. Além disso, também não é de forma alguma uma implementação de “melhores práticas”, pois pode criar sobrecarga adicional e é necessária apenas para instâncias específicas.
Pensamentos finais
Neste momento, parece que a navegação programática no SwiftUI sempre virá com certas ressalvas e considerações adicionais. Certifique-se de pensar cuidadosamente em sua navegação e considerar como você pode centralizar a forma como seus usuários se movem em seu aplicativo.
[ad_2]
Source link