Exemplo reprodutível mínimo (Xcode 11.2 beta, isso funciona no Xcode 11.1):
struct Parent: View {
var body: some View {
NavigationView {
Text("Hello World")
.navigationBarItems(
trailing: NavigationLink(destination: Child(), label: { Text("Next") })
)
}
}
}
struct Child: View {
@Environment(\.presentationMode) var presentation
var body: some View {
Text("Hello, World!")
.navigationBarItems(
leading: Button(
action: {
self.presentation.wrappedValue.dismiss()
},
label: { Text("Back") }
)
)
}
}
struct ContentView: View {
var body: some View {
Parent()
}
}
O problema parece estar em colocar meu NavigationLink
interior de um navigationBarItems
modificador aninhado dentro de uma visualização SwiftUI cuja visualização raiz é a NavigationView
. O relatório de falha indica que estou tentando acessar um controlador de exibição que não existe quando navego para frente Child
e depois para Parent
.
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Tried to pop to a view controller that doesn't exist.'
*** First throw call stack:
Se eu colocasse isso NavigationLink
no corpo da visualização como a abaixo, funciona muito bem.
struct Parent: View {
var body: some View {
NavigationView {
NavigationLink(destination: Child(), label: { Text("Next") })
}
}
}
Isso é um bug do SwiftUI ou comportamento esperado?
EDIT: Eu abri um problema com a Apple no assistente de feedback com o ID FB7423964
, caso alguém da Apple se preocupe em pesar :).
EDIT: meu ticket aberto no assistente de feedback indica que há mais de 10 problemas relatados semelhantes. Eles atualizaram a resolução com Resolution: Potential fix identified - For a future OS update
. Dedos cruzados que a correção chega logo.
EDIT: Isso foi corrigido no iOS 13.3!
ContentView.swift
. Farei uma edição na postagem, mas a falha só acontece quando você navega para frente e para trás.Respostas:
Este foi um ponto de dor para mim! Deixei-o até a maior parte do meu aplicativo ser concluída e eu tive o espaço da mente para lidar com as falhas.
Acho que todos podemos concordar que há algumas coisas incríveis no SwifUI, mas que a depuração pode ser difícil.
Na minha opinião, eu diria que este é um erro. Aqui está o meu raciocínio:
Se você quebrar a chamada de dispensa de PresentationMode em um atraso assíncrono de cerca de meio segundo, você deve descobrir que o programa não travará mais.
Isso sugere para mim que o bug é um comportamento inesperado, profundo na maneira como o SwiftUI faz interface com todos os outros códigos do UIKit para gerenciar as várias visualizações. Dependendo do seu código real, você poderá descobrir que, se houver alguma complexidade menor na exibição, a falha não ocorrerá. Por exemplo, se você estiver descartando de uma exibição para uma que tenha uma lista e essa lista esteja vazia, ocorrerá uma falha sem o atraso assíncrono. Por outro lado, se você tiver apenas uma entrada nessa exibição de lista, forçando uma iteração de loop para gerar a exibição pai, verá que a falha não ocorrerá.
Não sei ao certo quão robusta é minha solução de encerrar a chamada de demissão em um atraso. Eu tenho que testar muito mais. Se você tiver idéias sobre isso, entre em contato! Eu ficaria muito feliz em aprender com você!
fonte
.navigationBarItems()
pontos, por ser um bug.Isso também me frustrou por algum tempo. Nos últimos meses, dependendo da versão do Xcode, da versão do simulador e do tipo e / ou versão real do dispositivo, ele passou de um trabalho para outro, aparentemente aleatoriamente. No entanto, recentemente, ele falhou consistentemente para mim, então ontem eu mergulhei profundamente nele. Atualmente, estou usando o Xcode versão 11.2.1 (11B500).
Parece que o problema gira em torno da barra de navegação e da maneira como os botões foram adicionados a ele. Portanto, em vez de usar um NavigationLink () para o próprio botão, tentei usar um Button () padrão com uma ação que define uma var @State que ativa um NavigationLink oculto. Aqui está um substituto para o Parent's Robert View:
Para mim, isso funciona de maneira muito consistente em todos os simuladores e dispositivos reais.
Aqui estão as minhas visualizações auxiliares:
Aqui está um exemplo do uso:
fonte
Este é um erro grave e não consigo ver uma maneira adequada de contornar isso. Funcionou bem no iOS 13 / 13.1, mas 13.2 falha.
Você pode replicá-lo de uma maneira muito mais simples (esse código é literalmente tudo o que você precisa).
Espero que a Apple resolva o problema, pois certamente quebrará muitos aplicativos SwiftUI (incluindo os meus).
fonte
Como solução alternativa, com base na resposta de Chuck H acima, encapsulei o NavigationLink como um elemento oculto:
Em seguida, você pode usá-lo em um NavigationView (que é crucial) e acioná-lo a partir de um botão em uma barra de navegação:
Coloque isso nos comentários "// HACK"; assim, quando a Apple corrigir isso, você poderá substituí-lo.
fonte
Com base nas informações que vocês forneceram e, especialmente, em um comentário que o @Robert fez sobre a localização do NavigationView, encontrei uma maneira de solucionar o problema, pelo menos no meu cenário específico.
No meu caso, eu tinha um TabView incluído em um NavigationView como este:
Esse código falha quando todos relatam no iOS 13.2 e funcionam no iOS 13.1. Após algumas pesquisas, descobri uma solução alternativa para essa situação.
Basicamente, estou movendo o NavigationView para cada tela separadamente em cada guia como esta:
De alguma forma, vai contra a premissa de simplicidade da SwiftUI, mas funciona no iOS 13.2.
fonte
Xcode 11.2.1 Swift 5
ENTENDI! Levei alguns dias para descobrir isso ...
No meu caso, ao usar o SwiftUI, estou recebendo uma falha apenas se a parte inferior da minha lista se estender além da tela e, em seguida, tentar "mover" qualquer item da lista. O que acabei descobrindo é que, se houver muitas "coisas" embaixo do List (), ele trava em movimento. Por exemplo, abaixo da minha Lista () eu tinha um botão Texto (), Espaçador (), Botão (), Espaçador () (). Se eu comentei algum desses objetos, de repente não consegui recriar a falha. Não sei ao certo quais são as limitações, mas se você estiver recebendo esse erro, tente remover objetos abaixo da sua lista para ver se isso ajuda.
fonte
Embora eu não consiga ver nenhuma falha, seu código tem alguns problemas:
Ao definir o item principal, você realmente elimina o comportamento padrão das transições de navegação. (tente deslizar do lado principal para ver se funciona).
Portanto, não há necessidade de um botão lá. Apenas deixe como está e você terá um botão Voltar gratuito.
E não se esqueça, de acordo com a HIG , o título do botão Voltar deve mostrar para onde vai, não o que é! Portanto, tente definir um título para a primeira página para mostrá-lo no botão Voltar que aparece.
fonte
FWIW - As soluções acima sugerindo um Hack NavigationLink oculto ainda são a melhor solução alternativa no iOS 13.3b3. Também arquivei um FB7386339 pelo bem da posteridade e fui fechado da mesma forma que outros FBs acima mencionados: "Correção potencial identificada - para uma futura atualização do sistema operacional".
Dedos cruzados.
fonte
Foi resolvido no iOS 13.3. Basta atualizar seu sistema operacional e o xCode.
fonte
.buttonStyle(PlainButtonStyle())
modificador NavigationLink e tente novamente. deixe-me saber se você fez uma pergunta.