Como executar o Unwind segue programaticamente?

307

Usando o storyboard, isso é muito fácil. Você apenas arrasta a ação para "Sair". Mas como devo chamá-lo do meu código?

tadasz
fonte
33
Acho essa uma pergunta válida - eu mesma a fiz. Você pode executar um desenrolar segue programaticamente: 1. criando um segue manual (arraste com a tecla Ctrl do proprietário do arquivo até a saída), 2. dando um nome ao IB e, em seguida, 3. executando um normal -performSegueWithIdentifier: sender: no seu código.
Yang Meyer
6
Não deveria ter sido fechado IMO. Os usuários que votaram para encerrar esta pergunta certamente não parecem ter um histórico de Obj-C / Cocoa Touch.
LJ Wilson
Yang: Como você o nomeou?
31412 sarfata
Eu apenas uso [auto-dispensarViewControllerAnimated: SIM conclusão: nil]; para sair programaticamente. Não sei se é o caminho certo ou não.
tangqiaoboy
1
sarfata: Você primeiro cria um "desenrolar manual segue" pressionando a tecla Ctrl do viewcontroller para "Exit". Em seguida, você pode encontrar as instruções no Esboço do documento.
huggie

Respostas:

283
  1. Crie um segue manual ( ctrl-drag do proprietário do arquivo para sair),
  2. Escolha-o no menu esquerdo do controlador, abaixo do botão verde EXIT.

Escolha-o no menu esquerdo do controlador, abaixo do botão verde EXIT

Insira o Nome do Segue para relaxar.

Então, - (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender.com o seu segue, identifique-se.

Vadim
fonte
25
1) "Dono do arquivo" - não é essa terminologia antiga? Funcionou para mim controlar o arrasto do controlador de exibição para o ícone Sair. 2) Embora deva ser óbvio, o Xcode está procurando por uma declaração na Interface da IBAction que use um argumento UIStoryboardSegue; a palestra da sessão 407 da WWDC 2012 não mencionou isso e não colou esse código. Sem ele, meu ícone Exit não ficaria ativo ao arrastar o controle para ele. 3) É muito legal que no final da sua grande seta vermelha, no campo Ação, você possa pressionar a seta "ir lá"!
precisa saber é o seguinte
71
Para quem, como eu, ainda tem problemas para implementar esta resposta, reuni um passo a passo e um exemplo mais aprofundado neste repositório : github.com/bradley/iOSUnwindSegueProgramatically (Não tentando me anunciar, apenas bati minha cabeça contra a parede por horas a esta e vendo uma configuração de trabalho me ajuda).
bradleygriffith
3
@bradleygriffith Você é incrivelmente super incrível. Obrigado pela grande explicação!
Eli_Rozen
7
@bradleygriffith Eu gostaria que você tivesse feito uma resposta para que eu pudesse marcar isso também! Sua contribuição exclusiva foi estabelecer qual controlador de exibição obtém qual código . Não foi possível encontrar isso em nenhum lugar. Obrigado!
Aaron Vegh
3
A chave, para qualquer um que ainda não entendeu isso, é que o IBACTION precisa estar no controlador de exibição para o qual você está retornando, não no que você está atualmente. mencionado em qualquer outro lugar. Essa parte é crítica.
Axeva
163

Aqui está uma resposta completa com o Objetivo C e Swift:

1) Crie um IBActionsegue de desenrolamento no seu controlador de exibição de destino (para onde você deseja seguir). Em qualquer lugar do arquivo de implementação.

// Objective C

    - (IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue {

    }

// Swift

 @IBAction func unwindToContainerVC(segue: UIStoryboardSegue) {

    }

2) No controlador de exibição de origem (o controlador do qual você está seguindo), drag + arraste de "Nome da atividade" para sair. Você deve ver as instruções desenroladas criadas na etapa 1 no pop-up. (Caso não o veja, revise a etapa um). Escolha unwindToContainerVC: no pop-up ou qualquer que seja o nome do seu método para conectar seu controlador de origem ao IBAction.

insira a descrição da imagem aqui

3) Selecione as instruções no esboço do documento do controlador de exibição de origem do storyboard (ele será listado na parte inferior) e dê um identificador .

insira a descrição da imagem aqui

4) Chame o segue de desenrolamento usando este método no controlador de exibição de origem , substituindo seu nome de segue de desenrolamento.

// objetivo C

[self performSegueWithIdentifier:@"unwindToContainerVC" sender:self];

// Rápido

self.performSegueWithIdentifier("unwindToContainerVC", sender: self)

NB. Use a propriedade sourceViewController do parâmetro segue no método desenrolar para acessar quaisquer propriedades expostas no controlador de origem. Além disso, observe que a estrutura lida com a dispensa do controlador de origem. Se você deseja confirmar isso, adicione um método de desalocação ao controlador de origem com uma mensagem de log que deve ser disparada após a morte. Se o dealloc não disparar, você poderá ter um ciclo de retenção.

smileBot
fonte
2
Meu programa não trabalho, nem mesmo chamado(IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue
XHG
2
esta solução não funciona quando o controlador de vista, você está desenrolando para, não só existem em seu storyboard, aka não tem o costume de implementação de código
MNL
O @mnl não sabe exatamente o que está dizendo, mas funciona com cenas de storyboard ou pontas. Se você estiver criando uma cena do viewcontroller no código, não usaria nenhum método que "retorne" a IB em seu nome, o que é realmente nulo de qualquer maneira, uma vez que serve à finalidade de comunicação entre o código e a IB. Isso aborda o seu comentário?
smileBot
1
Sua foto mostrando o ctrl+dragde ViewControllerpara Exitfoi incrivelmente útil. Obrigado!
Kbpontius
Para o Swift 4.2, use: self.performSegue (withIdentifier: "unwindToVC", remetente: self)
Reefwing
81

bradleygriffithA resposta foi ótima. Eu dei o passo 10 e fiz uma captura de tela para simplificação. Esta é uma captura de tela no Xcode 6.

  1. Arraste com a tecla Control pressionada do ícone laranja para o ícone vermelho Sair para criar um desenrolar sem nenhuma ação / botão na exibição.

insira a descrição da imagem aqui

  1. Em seguida, selecione unwind seguena barra lateral:

insira a descrição da imagem aqui

  1. Defina uma cadeia de caracteres de identificador de segmento:

insira a descrição da imagem aqui

  1. Acesse esse identificador a partir do código:
[self performSegueWithIdentifier:@"unwindIdentifier" sender:self];
reitor
fonte
4
Primeiro de tudo, o método para desenrolar deve ser incluído dentro do arquivo UIViewController. Então sua solução irá funcionar #
Alex Cio
5
e você precisa definir o Identifier para este novo segue! Não esqueça disso.
kraag22
1
É possível criar a conexão "exit" no controlador de exibição de origem programaticamente?
Andrew Kirna 31/05/19
13

Eu usei o [self dismissViewControllerAnimated: YES completion: nil];que o levará de volta ao chamado ViewController.

Larry Gibson
fonte
6
Larry, essa é uma abordagem perfeitamente válida se você deseja retornar ao controlador de exibição anterior, ou seja, aquele que apresentou o que você está saindo agora. A questão surgiu porque o novo no Xcode 4.5 é a capacidade de "relaxar" de um controlador de exibição em algum lugar da ordem da apresentação para um controlador de exibição muito anterior. Consulte a sessão 407 da WWDC 2012 para obter detalhes.
precisa saber é o seguinte
11

Citando texto da Nota técnica da Apple sobre Desdobrar segmento: Para adicionar uma sequência de desenrolamento que só será acionada de forma programática, mantenha pressionada a tecla Ctrl + arraste do ícone do controlador de exibição da cena para o ícone de saída e, em seguida, selecione uma ação de desenrolar para a nova sequência no menu pop-up.

Link para Nota Técnica

Vishal Chaudhry
fonte
6

A resposta de Vishal Chaudhry acima funcionou para mim. Eu também adicionaria isso para acionar manualmente o seque usando:

[self performSegueWithIdentifier:@"mySegueName" sender:self];

a partir do ViewController, você também deve selecionar as etapas de desenrolamento na Cena do ViewController no storyboard e na visualização de propriedades no RHS, para garantir que o campo Identificador contenha o nome que você está se referindo no código ("mySegueName" no exemplo acima )

Se você omitir esta etapa, a linha acima emitirá uma exceção que o nome do seque não é conhecido.

Jason Crocker
fonte
3

Solução compatível com versões anteriores que funcionará para versões anteriores ao ios6, para os interessados:

- (void)unwindToViewControllerOfClass:(Class)vcClass animated:(BOOL)animated {

    for (int i=self.navigationController.viewControllers.count - 1; i >= 0; i--) {
        UIViewController *vc = [self.navigationController.viewControllers objectAtIndex:i];
        if ([vc isKindOfClass:vcClass]) {
            [self.navigationController popToViewController:vc animated:animated];
            return;
        }
    }
}
Joel Teply
fonte
2
Desenrolar os passos faz muito mais do que retornar a uma determinada classe em uma pilha do controlador de navegação.
9788 Steve Moser
2

SWIFT 4 :

1. Crie uma @IBAction com segue dentro do controlador que você deseja descontrair:

    @IBAction func unwindToVC(segue: UIStoryboardSegue) {

    }

2. No storyboard, no controlador que você deseja seguir (desenrolar) de ctrl + arraste do sinal do controlador para sair do sinal e escolha o método que você criou anteriormente:

insira a descrição da imagem aqui

3. Agora você pode notar que, no esboço do documento, você tem uma nova linha com o título "Desenrolar segue ....". Agora você deve clicar nesta linha e abrir o inspetor de atributos para definir o identificador (no meu caso, descontrairSegueIdentifier ).

insira a descrição da imagem aqui

4. Você está quase pronto! Agora você precisa abrir o controlador de exibição do qual deseja relaxar e criar algum método que execute o seguinte. Por exemplo, você pode adicionar o botão, conectá-lo ao código com @IBAction , depois dentro deste IBAction adicione o método perfromSegue (withIdentifier: sender :) :

     @IBAction func unwindToSomeVCWithSegue(_ sender: UIButton) {
         performSegue(withIdentifier: "unwindSegueIdentifier", sender: nil)
     }

Então é isso que você precisa fazer!

wm.p1us
fonte
É possível criar a conexão "exit" no controlador de exibição de origem programaticamente?
Andrew Kirna 31/05/19
1

Swift 4.2, Xcode 10+

Para aqueles que se perguntam como fazer isso com os VCs não configurados pelo storyboard (aqueles que chegam a essa pergunta pesquisando "programaticamente" + "desenrolar segue").

Como você não pode configurar um desenrolar segue programaticamente, a solução programática mais simples é chamar:

navigationController?.popToRootViewController(animated: true)

que exibirá todos os controladores de exibição na pilha de volta ao seu controlador de exibição raiz.


Para exibir apenas o controlador de exibição mais alto da pilha de navegação, use:

navigationController?.popViewController(animated: true)

10623169
fonte
1
isso geralmente é mais do que você deseja - para voltar atrás, basta fazer: [self.navigationController popViewControllerAnimated: YES];
Andy Weinstein
Na verdade, eu adicionei isso à minha resposta - obrigado @AndyWeinstein
10623169 23/03
0

FYI: Para que a resposta do @ Vadim funcione com uma ação manual de desenrolamento chamada de dentro de um View Controller, você deve colocar o comando:

[self performSegueWithIdentifier:(NSString*) identifier sender:(id) sender];

dentro do método de classe substituída viewDidAppear assim:

-(void) viewDidAppear:(BOOL) animated
{
    [super viewDidAppear: animated];

    [self performSegueWithIdentifier:@"SomeSegueIdentifier" sender:self];
}

Se você colocá-lo em outros métodos ViewController, como viewDidLoad ou viewWillAppear, ele será ignorado.

John Verco
fonte
3
Definitivamente errado. Ligue para performSegueWithIdentifier de onde quiser.
smileBot
Isso não seria apenas executar movimentos de desenrolar assim que a exibição for carregada? Em vez de executar quando você quiser, por exemplo, depois de pressionar um botão.
Pahnev
@Pahnev sim, seria. Não sei como essa resposta recebeu votos positivos. Chamando performSegueWithIdentfierfaz exatamente isso: realizar o segue de um ViewController para outro
ezcoding
Completamente errado. Seria apenas rebobinar imediatamente no lançamento.
Lee Probert