Eu estava brincando com o SwiftUI e quero poder voltar à visualização anterior ao tocar em um botão, o mesmo que usamos popViewControllerdentro de um UINavigationController. Existe uma maneira fornecida de fazer isso até agora?
Também tentei NavigationDestinationLinkfazer isso sem sucesso.
struct AView: View {
var body: some View {
NavigationView {
NavigationButton(destination: BView()) {
Text("Go to B")
}
}
}
}
struct BView: View {
var body: some View {
Button(action: {
// Trying to go back to the previous view
// previously: navigationController.popViewController(animated: true)
}) {
Text("Come back to A")
}
}
}
Modifique sua estrutura BView da seguinte maneira. O botão funcionará exatamente como popViewController no UIKit.
struct BView: View {
@Environment(\.presentationMode) var mode: Binding<PresentationMode>
var body: some View {
Button(action: { self.mode.wrappedValue.dismiss() })
{ Text("Come back to A") }
}
}
Agora existe uma maneira de inserir programaticamente um NavigationView, se desejar. Isso está na versão beta 5.
Observe que você não precisa do botão Voltar. Você pode acionar programaticamente a propriedade showSelf em DetailView da maneira que desejar. E você não precisa exibir o texto "Push" no mestre. Isso poderia ser um EmptyView (), criando assim uma segue invisível.
(A nova funcionalidade NavigationLink assume o controle do NavigationDestinationLink obsoleto)
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
MasterView()
}
}
}
struct MasterView: View {
@State var showDetail = false
var body: some View {
VStack {
NavigationLink(destination: DetailView(showSelf: $showDetail), isActive: $showDetail) {
Text("Push")
}
}
}
}
struct DetailView: View {
@Binding var showSelf: Bool
var body: some View {
Button(action: {
self.showSelf = false
}) {
Text("Pop")
}
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
Use @Environment(\.presentationMode) var presentationModepara voltar a vista anterior. Verifique o código abaixo para mais compreensão.
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
Color.gray.opacity(0.2)
NavigationLink(destination: NextView(), label: {Text("Go to Next View").font(.largeTitle)})
}.navigationBarTitle(Text("This is Navigation"), displayMode: .large)
.edgesIgnoringSafeArea(.bottom)
}
}
}
struct NextView: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
ZStack {
Color.gray.opacity(0.2)
}.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: Button(action: {
self.presentationMode.wrappedValue.dismiss()
}, label: { Image(systemName: "arrow.left") }))
.navigationBarTitle("", displayMode: .inline)
}
}
struct NameRow: View {
var name: String
var body: some View {
HStack {
Image(systemName: "circle.fill").foregroundColor(Color.green)
Text(name)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Com variáveis de estado. Tente isso.
struct ContentViewRoot: View {
@State var pushed: Bool = false
var body: some View {
NavigationView{
VStack{
NavigationLink(destination:ContentViewFirst(pushed: self.$pushed), isActive: self.$pushed) { EmptyView() }
.navigationBarTitle("Root")
Button("push"){
self.pushed = true
}
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct ContentViewFirst: View {
@Binding var pushed: Bool
@State var secondPushed: Bool = false
var body: some View {
VStack{
NavigationLink(destination: ContentViewSecond(pushed: self.$pushed, secondPushed: self.$secondPushed), isActive: self.$secondPushed) { EmptyView() }
.navigationBarTitle("1st")
Button("push"){
self.secondPushed = true;
}
}
}
}
struct ContentViewSecond: View {
@Binding var pushed: Bool
@Binding var secondPushed: Bool
var body: some View {
VStack{
Spacer()
Button("PopToRoot"){
self.pushed = false
} .navigationBarTitle("2st")
Spacer()
Button("Pop"){
self.secondPushed = false
} .navigationBarTitle("1st")
Spacer()
}
}
}

Parece que muitas funcionalidades básicas de navegação apresentam muitos bugs, o que é decepcionante e talvez valha a pena abandoná-las por enquanto para economizar horas de frustração. Para mim, PresentationButton é o único que funciona. As guias TabbedView não funcionam corretamente e NavigationButton não funciona para mim. Soa como YMMV se NavigationButton funcionar para você.
Espero que eles consertem ao mesmo tempo que consertam o preenchimento automático, o que nos daria uma visão muito melhor do que está disponível para nós. Enquanto isso, estou relutantemente codificando em torno disso e fazendo anotações para quando as correções forem lançadas. É chato ter que descobrir se estamos fazendo algo errado ou se simplesmente não funciona, mas isso é beta para você!
Isso parece funcionar para mim no watchOS (não tentei no iOS):
@Environment(\.presentationMode) var presentationMode
E então, quando você precisar estourar
self.presentationMode.wrappedValue.dismiss()
Atualização: a API NavigationDestinationLink nesta solução foi descontinuada a partir do iOS 13 Beta 5. Agora é recomendado usar NavigationLink com uma associação isActive.
Eu descobri uma solução para push / popping programático de visualizações em um NavigationView usando NavigationDestinationLink.
Aqui está um exemplo simples:
import Combine
import SwiftUI
struct DetailView: View {
var onDismiss: () -> Void
var body: some View {
Button(
"Here are details. Tap to go back.",
action: self.onDismiss
)
}
}
struct MainView: View {
var link: NavigationDestinationLink<DetailView>
var publisher: AnyPublisher<Void, Never>
init() {
let publisher = PassthroughSubject<Void, Never>()
self.link = NavigationDestinationLink(
DetailView(onDismiss: { publisher.send() }),
isDetail: false
)
self.publisher = publisher.eraseToAnyPublisher()
}
var body: some View {
VStack {
Button("I am root. Tap for more details.", action: {
self.link.presented?.value = true
})
}
.onReceive(publisher, perform: { _ in
self.link.presented?.value = false
})
}
}
struct RootView: View {
var body: some View {
NavigationView {
MainView()
}
}
}
Eu escrevi sobre isso em uma postagem do blog aqui .
EDIT: esta resposta aqui é melhor do que a minha, mas ambas funcionam: SwiftUI dispensar modal
O que você realmente quer (ou deveria querer) é uma apresentação modal, que várias pessoas mencionaram aqui. Se você seguir esse caminho, definitivamente precisará ser capaz de dispensar programaticamente o modal, e Erica Sadun tem um ótimo exemplo de como fazer isso aqui:https://ericasadun.com/2019/06/16/swiftui-modal-presentation/
Dada a diferença entre a codificação declarativa e a codificação imperativa, a solução pode não ser óbvia (alternar um bool para falso para descartar o modal, por exemplo), mas faz sentido se o estado do seu modelo for a fonte da verdade, ao invés do estado da própria IU.
Aqui está minha visão rápida do exemplo de Erica, usando um vínculo passado no TestModal para que ele possa dispensar a si mesmo sem ter que ser um membro do próprio ContentView (como o de Erica é, para simplificar).
struct TestModal: View {
@State var isPresented: Binding<Bool>
var body: some View {
Button(action: { self.isPresented.value = false }, label: { Text("Done") })
}
}
struct ContentView : View {
@State var modalPresented = false
var body: some View {
NavigationView {
Text("Hello World")
.navigationBarTitle(Text("View"))
.navigationBarItems(trailing:
Button(action: { self.modalPresented = true }) { Text("Show Modal") })
}
.presentation(self.modalPresented ? Modal(TestModal(isPresented: $modalPresented)) {
self.modalPresented.toggle()
} : nil)
}
}
Abaixo funciona para mim no XCode11 GM
self.myPresentationMode.wrappedValue.dismiss()
em vez de NavigationButton use Navigation DestinationLink
mas você deve importar Combine
struct AView: View {
var link: NavigationDestinationLink<BView>
var publisher: AnyPublisher<Void, Never>
init() {
let publisher = PassthroughSubject<Void, Never>()
self.link = NavigationDestinationLink(
BView(onDismiss: { publisher.send() }),
isDetail: false
)
self.publisher = publisher.eraseToAnyPublisher()
}
var body: some View {
NavigationView {
Button(action:{
self.link.presented?.value = true
}) {
Text("Go to B")
}.onReceive(publisher, perform: { _ in
self.link.presented?.value = false
})
}
}
}
struct BView: View {
var onDismiss: () -> Void
var body: some View {
Button(action: self.onDismiss) {
Text("Come back to A")
}
}
}
Xcode 11.3
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
...
// If animation is strange, try this.
DispatchQueue.main.async {
self.presentationMode.wrappedValue.dismiss()
}
Você também pode fazer isso com .sheet
.navigationBarItems(trailing: Button(action: {
self.presentingEditView.toggle()
}) {
Image(systemName: "square.and.pencil")
}.sheet(isPresented: $presentingEditView) {
EditItemView()
})
No meu caso, eu o uso a partir de um item da barra de navegação à direita, então você tem que criar a visão ( EditItemView()no meu caso) que você vai exibir nessa visão modal.
https://developer.apple.com/documentation/swiftui/view/sheet(ispresented:ondismiss:content:)
Jana Duggar foi aberta sobre sua busca pelo amor. Aqui está tudo o que ela disse sobre o assunto e sua janela de cinco anos para o casamento.
O astro de 'Outlander', Sam Heughan, revelou recentemente o que vai levar do set para relembrar Jamie Fraser, o papel que o tornou uma estrela.
'She Loves You' foi escrita em uma hora, gravada em um dia, e foi a música dos Beatles com uma de suas melhores apresentações de sua carreira.
Dolly Parton e sua avó Bessie tiveram um relacionamento especial. Vovó Parton estava muito doente, mas isso não impediu Dolly de pregar uma peça nela.
Você pode achar que o carvalho ou a nogueira são madeiras resistentes, mas quando se trata da madeira mais dura do mundo, elas nem chegam perto.
O oceano é repleto de beleza, mas também esconde algumas das criaturas marinhas mais assustadoras do planeta. Muitos desses animais espreitam nas profundezas do oceano, no mundo escuro e de alta pressão do fundo do mar.
Se você está enfrentando criaturas hostis ou se preparando para cenários PvP, conhecer os melhores encantamentos de espada no Minecraft pode te dar uma grande vantagem. Encantar espadas permite causar mais dano, aumentar a quantidade de itens obtidos de criaturas e prolongar a durabilidade da sua espada.
Quando as pessoas falam sobre países socialistas, geralmente imaginam o controle total do governo e a ausência de propriedade privada. Mas, na prática, as economias socialistas variam muito.
“Children” traz uma participação especial de grande nome e algumas notícias devastadoras
Este RAV4 está em excelentes condições e está preparado para um jogo de cadeiras musicais.
Imagens de drone capturaram bombeiros parecendo lutar para apagar o incêndio.
Eyes of Wakanda está diretamente relacionado ao MCU, além de atualizações sobre X-Men '97, What If..., Demolidor e muito mais.
O anel de noivado de Kate Middleton pertenceu à Princesa Diana antes do Príncipe William pedi-la em casamento. Descubra tudo o que há para saber sobre a peça histórica aqui.
John Cleese se casou com sua esposa, Jennifer Wade, em 2012. Aqui está tudo o que você precisa saber sobre a esposa de John Cleese, Jennifer Wade.
Patton Oswalt se casou com sua esposa, a também atriz Meredith Salenger, em 2017. Aqui está tudo o que você precisa saber sobre a esposa de Patton Oswalt, Meredith Salenger.
Mena Suvari é casada com o marido Michael Hope desde 2018. Aqui está tudo o que você precisa saber sobre o marido de Mena Suvari.
Isso me atinge De repente, como tantas vezes acontece É o meio do caminho tudo de novo <Não, não aquele no Pacífico, seu marrom, aquele no carnaval> Todas as manchetes em voz alta…..
Em 2022, com o lançamento do GPT-3, a habilidade de escrita parece se tornar menos importante. Com a IA, pessoas com redação ruim também podem gerar funcionários de qualidade.
No mundo acelerado e competitivo de hoje, a carreira desempenha um papel significativo no crescimento pessoal, na estabilidade financeira e na satisfação geral com a vida. No entanto, muitos indivíduos encontram-se presos em um ciclo implacável de estagnação e insatisfação, definhando gradualmente em suas vidas profissionais.
Na semana passada, notei um comunicado de imprensa, enviado via PressGazette (um site de notícias da mídia britânica). O artigo anunciava que a Acast, a empresa de publicidade e hospedagem de podcast Scandi, lideraria um consórcio de "provavelmente os editores mais influentes" em podcasting.