Esta pergunta parece ser muito popular aqui no stackoverflow, então pensei em tentar e dar uma resposta melhor para ajudar pessoas começando no mundo do iOS como eu.
Espero que esta resposta seja clara o suficiente para as pessoas entenderem e que não perdi nada.
Passando dados para a frente
Passando dados para um controlador de exibição de outro controlador de exibição. Você usaria esse método se desejasse passar um objeto / valor de um controlador de exibição para outro controlador de exibição que possa estar pressionando em uma pilha de navegação.
Neste exemplo, teremos ViewControllerA
eViewControllerB
Para passar um BOOL
valor de ViewControllerA
para ViewControllerB
, faríamos o seguinte.
em ViewControllerB.h
criar uma propriedade para oBOOL
@property (nonatomic, assign) BOOL isSomethingEnabled;
em que ViewControllerA
você precisa falar sobre ViewControllerB
isso, use um
#import "ViewControllerB.h"
Então, onde você deseja carregar a visualização, por exemplo. didSelectRowAtIndex
ou alguns dos quais IBAction
você precisa definir a propriedade ViewControllerB
antes de enviá-la para a pilha de navegação.
ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
viewControllerB.isSomethingEnabled = YES;
[self pushViewController:viewControllerB animated:YES];
Isto irá definir isSomethingEnabled
em ViewControllerB
que BOOL
valor YES
.
Passando dados para frente usando segmentos
Se você estiver usando Storyboards, provavelmente usará seques e precisará deste procedimento para passar os dados adiante. Isso é semelhante ao acima, mas em vez de passar os dados antes de você pressionar o controlador de exibição, use um método chamado
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
Então, para passar de BOOL
from ViewControllerA
para ViewControllerB
, faríamos o seguinte:
em ViewControllerB.h
criar uma propriedade para oBOOL
@property (nonatomic, assign) BOOL isSomethingEnabled;
em que ViewControllerA
você precisa falar sobre ViewControllerB
isso, use um
#import "ViewControllerB.h"
Crie um segue de ViewControllerA
para ViewControllerB
no storyboard e dê um identificador, neste exemplo, chamaremos de"showDetailSegue"
Em seguida, precisamos adicionar o método ao ViewControllerA
que é chamado quando qualquer segue é executada, por isso, precisamos detectar qual segue foi chamado e, em seguida, fazer alguma coisa. Em nosso exemplo, verificaremos "showDetailSegue"
e, se isso for executado, passaremos nosso BOOL
valor paraViewControllerB
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:@"showDetailSegue"]){
ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController;
controller.isSomethingEnabled = YES;
}
}
Se você tiver suas visualizações incorporadas em um controlador de navegação, precisará alterar ligeiramente o método acima para o seguinte
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:@"showDetailSegue"]){
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
ViewControllerB *controller = (ViewControllerB *)navController.topViewController;
controller.isSomethingEnabled = YES;
}
}
Isto irá definir isSomethingEnabled
em ViewControllerB
que BOOL
valor YES
.
Passando dados de volta
Para passar dados de volta ViewControllerB
para ViewControllerA
você precisar usar Protocolos e Delegados ou Blocos , o último pode ser usado como um mecanismo pouco acoplado para retornos de chamada.
Para fazer isso, faremos ViewControllerA
um delegado de ViewControllerB
. Isso permite ViewControllerB
enviar uma mensagem de volta para ViewControllerA
nos permitir enviar dados de volta.
Para ViewControllerA
ser um delegado ViewControllerB
dele deve estar em conformidade com ViewControllerB
o protocolo que devemos especificar. Isso informa ViewControllerA
quais métodos ele deve implementar.
Em ViewControllerB.h
, abaixo de #import
, mas acima de @interface
você especificar o protocolo.
@class ViewControllerB;
@protocol ViewControllerBDelegate <NSObject>
- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
@end
próximo ainda no ViewControllerB.h
você precisa configurar uma delegate
propriedade e sintetizar emViewControllerB.m
@property (nonatomic, weak) id <ViewControllerBDelegate> delegate;
Em ViewControllerB
chamamos uma mensagem no delegate
quando aparecer o controlador de vista.
NSString *itemToPassBack = @"Pass this value back to ViewControllerA";
[self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];
É para isso ViewControllerB
. Agora ViewControllerA.h
, diga ViewControllerA
para importar ViewControllerB
e estar em conformidade com seu protocolo.
#import "ViewControllerB.h"
@interface ViewControllerA : UIViewController <ViewControllerBDelegate>
Em ViewControllerA.m
implementar o seguinte método do nosso protocolo
- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item
{
NSLog(@"This was returned from ViewControllerB %@",item);
}
Antes de enviar viewControllerB
para a pilha de navegação, precisamos informar ViewControllerB
que ViewControllerA
é seu representante, caso contrário, obteremos um erro.
ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
viewControllerB.delegate = self
[[self navigationController] pushViewController:viewControllerB animated:YES];
Referências
- Usando a delegação para se comunicar com outros controladores de exibição no Guia de programação do controlador de exibição
- Delegar Padrão
NSNotification center
É outra maneira de transmitir dados.
// add observer in controller(s) where you want to receive data
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeepLinking:) name:@"handleDeepLinking" object:nil];
-(void) handleDeepLinking:(NSNotification *) notification {
id someObject = notification.object // some custom object that was passed with notification fire.
}
// post notification
id someObject;
[NSNotificationCenter.defaultCenter postNotificationName:@"handleDeepLinking" object:someObject];
Passando dados de volta de uma classe para outra (Uma classe pode ser qualquer controlador, gerente de rede / sessão, subclasse UIView ou qualquer outra classe)
Blocos são funções anônimas.
Este exemplo passa dados do Controlador B para o Controlador A
definir um bloco
@property void(^selectedVoucherBlock)(NSString *); // in ContollerA.h
adicione manipulador de bloco (ouvinte)
onde você precisa de um valor (por exemplo, você precisa de sua resposta de API no ControllerA ou precisa de dados do ContorllerB em A)
// in ContollerA.m
- (void)viewDidLoad {
[super viewDidLoad];
__unsafe_unretained typeof(self) weakSelf = self;
self.selectedVoucherBlock = ^(NSString *voucher) {
weakSelf->someLabel.text = voucher;
};
}
Vá para o controlador B
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ControllerB *vc = [storyboard instantiateViewControllerWithIdentifier:@"ControllerB"];
vc.sourceVC = self;
[self.navigationController pushViewController:vc animated:NO];
bloco de fogo
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath {
NSString *voucher = vouchersArray[indexPath.row];
if (sourceVC.selectVoucherBlock) {
sourceVC.selectVoucherBlock(voucher);
}
[self.navigationController popToViewController:sourceVC animated:YES];
}
Outro exemplo de trabalho para blocos
@class ViewControllerB;
definição acima da @protocol? Sem ele eu recebo um erro "Tipo esperado" na ViewControllerB na linha:- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
dentro da@protocol
declaraçãoNavigationController
você tem que usar[self.navigationController pushViewController:viewController animated:YES];
em vez[self pushViewController:viewControllerB animated:YES];
Rápido
Há toneladas e muitas explicações aqui e ao redor do StackOverflow, mas se você é iniciante, está apenas tentando obter algo básico para o trabalho, tente assistir a este tutorial do YouTube (foi o que me ajudou a finalmente entender como fazê-lo).
Passando dados para o próximo View Controller
A seguir, é apresentado um exemplo baseado no vídeo. A idéia é passar uma sequência do campo de texto no First View Controller para o rótulo no Second View Controller.
Crie o layout do storyboard no Interface Builder. Para fazer as etapas, basta Controlclicar no botão e arrastar para o Second View Controller.
First View Controller
O código para o First View Controller é
Second View Controller
E o código para o Second View Controller é
Não esqueça
UITextField
eUILabel
.Passando dados de volta para o View Controller anterior
Para passar dados do segundo controlador de exibição para o primeiro controlador de exibição, use um protocolo e um delegado . Este vídeo é uma visão muito clara desse processo:
A seguir, é apresentado um exemplo baseado no vídeo (com algumas modificações).
Crie o layout do storyboard no Interface Builder. Novamente, para fazer o seguinte, basta Controlarrastar do botão para o Second View Controller. Defina o identificador segue para
showSecondViewController
. Além disso, não esqueça de conectar as saídas e ações usando os nomes no código a seguir.First View Controller
O código para o First View Controller é
Observe o uso do nosso
DataEnteredDelegate
protocolo personalizado .Controlador e protocolo Second View
O código para o segundo controlador de exibição é
Observe que
protocol
está fora da classe View Controller.É isso aí. Ao executar o aplicativo agora, você poderá enviar dados do segundo controlador de exibição para o primeiro.
fonte
secondViewController.delegate = self
significa "Eu concordo em ser o trabalhador do chefe". Veja esta resposta para outro exemplo e mais explicações.OM no MVC é para "Model" e no paradigma MVC o papel das classes de modelo é gerenciar os dados de um programa. Um modelo é o oposto de uma visão - uma visão sabe como exibir dados, mas não sabe nada sobre o que fazer com dados, enquanto um modelo sabe tudo sobre como trabalhar com dados, mas nada sobre como exibi-los. Os modelos podem ser complicados, mas não precisam. O modelo do seu aplicativo pode ser tão simples quanto uma matriz de strings ou dicionários.
O papel de um controlador é mediar entre vista e modelo. Portanto, eles precisam de uma referência para um ou mais objetos de exibição e um ou mais objetos de modelo. Digamos que seu modelo é uma matriz de dicionários, com cada dicionário representando uma linha na sua tabela. A visualização raiz do seu aplicativo exibe essa tabela e pode ser responsável por carregar a matriz de um arquivo. Quando o usuário decide adicionar uma nova linha à tabela, ele toca em algum botão e seu controlador cria um novo dicionário (mutável) e o adiciona à matriz. Para preencher a linha, o controlador cria um controlador de exibição de detalhes e fornece o novo dicionário. O controlador de exibição de detalhes preenche o dicionário e retorna. O dicionário já faz parte do modelo, então nada mais precisa acontecer.
fonte
Existem várias maneiras pelas quais os dados podem ser recebidos para uma classe diferente no iOS. Por exemplo -
NSUserDefaults
- para acessá-lo mais tardeMas, para o cenário simples de passar um valor para uma classe diferente cuja alocação é feita na classe atual, o método mais comum e preferido seria a configuração direta de valores após a alocação. Isto se faz do seguinte modo:-
Podemos entender isso usando dois controladores - Controller1 e Controller2
Suponha que na classe Controller1 você deseje criar o objeto Controller2 e enviá-lo com um valor String sendo passado. Isso pode ser feito da seguinte maneira: -
Na implementação da classe Controller2, haverá esta função como
Você também pode definir diretamente as propriedades da classe Controller2 da maneira semelhante a esta:
Para passar vários valores, você pode usar vários parâmetros como: -
Ou, se você precisar passar mais de 3 parâmetros relacionados a um recurso comum, poderá armazenar os valores em uma classe Model e passar esse modelObject para a próxima classe
Então, resumindo, se você quiser -
Espero que isto ajude
fonte
Após mais pesquisas, parecia que Protocolos e Delegados é a maneira correta / a Apple preferia fazer isso.
Acabei usando este exemplo
Compartilhando dados entre os controladores de exibição e outros objetos no iPhone Dev SDK
Funcionou bem e me permitiu passar uma string e uma matriz para frente e para trás entre meus pontos de vista.
Obrigado por toda sua ajuda
fonte
Acho a versão mais simples e elegante com blocos que passam. Vamos nomear o controlador de exibição que aguarda os dados retornados como "A" e retornar o controlador de exibição como "B". Neste exemplo, queremos obter 2 valores: primeiro do tipo 1 e segundo do tipo 2.
Supondo que usamos o Storyboard, o primeiro controlador define o bloco de retorno de chamada, por exemplo, durante a preparação do segue:
e o controlador de exibição "B" deve declarar a propriedade de retorno de chamada, BViewController.h:
Do que no arquivo de implementação BViewController.m, depois que desejamos que os valores retornem, nosso retorno de chamada deve ser chamado:
Uma coisa a lembrar é que o uso de bloco geralmente precisa gerenciar referências fortes e fracas, como explicado aqui
fonte
Há algumas informações boas em muitas das respostas dadas, mas nenhuma aborda a questão completamente.
A pergunta é sobre a passagem de informações entre os controladores de exibição. O exemplo específico dado pergunta sobre a passagem de informações entre visualizações, mas, dada a novidade auto-declarada para o iOS, o pôster original provavelmente significava entre viewControllers, não entre visualizações (sem nenhum envolvimento dos ViewControllers). Parece que todas as respostas se concentram em dois controladores de exibição, mas e se o aplicativo evoluir para envolver mais de dois controladores de exibição na troca de informações?
O pôster original também perguntou sobre Singletons e o uso do AppDelegate . Essas perguntas precisam ser respondidas.
Para ajudar qualquer pessoa que esteja olhando para essa pergunta, que deseja uma resposta completa, tentarei fornecê-la.
Cenários de aplicação
Em vez de ter uma discussão abstrata altamente hipotética, ajuda a ter aplicações concretas em mente. Para ajudar a definir uma situação de controlador de duas visualizações e uma situação de controlador de mais de duas visualizações, vou definir dois cenários de aplicação concretos.
Cenário 1: no máximo dois controladores de exibição precisam compartilhar informações. Veja o diagrama um.
Existem dois controladores de exibição no aplicativo. Há um ViewControllerA (formulário de entrada de dados) e o View Controller B (lista de produtos). Os itens selecionados na lista de produtos devem corresponder aos itens exibidos na caixa de texto no formulário de entrada de dados. Nesse cenário, ViewControllerA e ViewControllerB devem se comunicar diretamente entre si e com nenhum outro controlador de exibição.
Cenário dois : mais de dois controladores de exibição precisam compartilhar as mesmas informações. Veja o diagrama dois.
Existem quatro controladores de exibição no aplicativo. É um aplicativo baseado em guias para gerenciar o inventário doméstico. Três controladores de exibição apresentam visualizações filtradas de maneira diferente dos mesmos dados:
Sempre que um item individual é criado ou editado, ele também deve ser sincronizado com os outros controladores de exibição. Por exemplo, se adicionarmos um barco no ViewControllerD, mas ele ainda não estiver seguro, o barco deverá aparecer quando o usuário acessar o ViewControllerA (Itens de luxo) e também o ViewControllerC (inventário doméstico inteiro), mas não quando o usuário acessar o ViewControllerB (itens não segurados). Precisamos nos preocupar não apenas com a adição de novos itens, mas também com a exclusão de itens (que podem ser permitidos em qualquer um dos quatro controladores de exibição) ou com a edição de itens existentes (que podem ser permitidos no "Formulário para adicionar novo item", redirecionando o mesmo para edição).
Como todos os controladores de exibição precisam compartilhar os mesmos dados, todos os quatro controladores de exibição precisam permanecer sincronizados e, portanto, deve haver algum tipo de comunicação com todos os outros controladores de exibição, sempre que um único controlador de exibição altera os dados subjacentes. Deveria ser bastante óbvio que não queremos que cada controlador de visualização se comunique diretamente entre si neste cenário. Caso isso não seja óbvio, considere se tivéssemos 20 controladores de exibição diferentes (em vez de apenas 4). Quão difícil e propenso a erros seria notificar cada um dos outros 19 controladores de visualização sempre que um controlador de visualização fazia uma alteração?
As Soluções: Delegados e o Padrão do Observador, e Singletons
No cenário um, temos várias soluções viáveis, pois outras respostas deram
No cenário dois, temos outras soluções viáveis:
Um singleton é uma instância de uma classe, sendo a única instância existente durante sua vida útil. Um singleton recebe esse nome pelo fato de ser a única instância. Normalmente, os desenvolvedores que usam singletons têm métodos de classe especiais para acessá-los.
Agora que entendemos o que é um singleton, vamos discutir como um singleton se encaixa no padrão de observador. O padrão observador é usado para um objeto responder a alterações de outro objeto. No segundo cenário, temos quatro controladores de exibição diferentes, que todos desejam saber sobre alterações nos dados subjacentes. Os "dados subjacentes" devem pertencer a uma única instância, um singleton. O "conhecimento sobre mudanças" é realizado observando as alterações feitas no singleton.
O aplicativo de inventário doméstico teria uma única instância de uma classe projetada para gerenciar uma lista de itens de inventário. O gerente gerenciava uma coleção de itens domésticos. A seguir está uma definição de classe para o gerenciador de dados:
Quando a coleção de itens do inventário doméstico é alterada, os controladores de exibição precisam estar cientes dessa alteração. A definição de classe acima não torna óbvio como isso acontecerá. Precisamos seguir o padrão do observador. Os controladores de exibição devem observar formalmente o sharedManager. Existem duas maneiras de observar outro objeto:
No cenário dois, não temos uma única propriedade do HouseholdInventoryManager que pode ser observada usando o KVO. Como não temos uma propriedade única que seja facilmente observável, o padrão do observador, nesse caso, deve ser implementado usando o NSNotificationCenter. Cada um dos quatro controladores de exibição assinaria notificações, e o sharedManager enviaria notificações ao centro de notificações quando apropriado. O gerente de inventário não precisa saber nada sobre os controladores de exibição ou instâncias de outras classes que possam estar interessadas em saber quando a coleção de itens de inventário é alterada; o NSNotificationCenter cuida desses detalhes de implementação. Os Controladores de exibição simplesmente assinam notificações e o gerenciador de dados simplesmente publica notificações.
Muitos programadores iniciantes aproveitam o fato de que sempre há exatamente um Delegado de Aplicativo durante a vida útil do aplicativo, que é acessível globalmente. Os programadores iniciantes usam esse fato para inserir objetos e funcionalidades no appDelegate como uma conveniência para acessar de qualquer outro lugar no aplicativo. Só porque o AppDelegate é um singleton não significa que ele deve substituir todos os outros singletons. Essa é uma prática ruim, pois coloca muita carga em uma classe, quebrando boas práticas orientadas a objetos. Cada classe deve ter um papel claro que seja facilmente explicado, geralmente apenas pelo nome da classe.
Sempre que o seu Application Delegate começar a ficar inchado, comece a remover a funcionalidade em singletons. Por exemplo, a Core Data Stack não deve ser deixada no AppDelegate, mas deve ser colocada em sua própria classe, a coreDataManager.
Referências
fonte
O OP não mencionou os controladores de exibição, mas muitas das respostas o fazem, e eu queria compartilhar com o que alguns dos novos recursos do LLVM permitem tornar isso mais fácil quando se deseja passar dados de um controlador de exibição para outro e, em seguida, obtendo alguns resultados de volta.
Os seguimentos do storyboard, os blocos ARC e LLVM tornam isso mais fácil do que nunca para mim. Algumas respostas acima mencionadas storyboards e segues já, mas ainda dependiam de delegação. A definição de delegados certamente funciona, mas algumas pessoas podem achar mais fácil passar ponteiros ou blocos de código.
Com UINavigators e segues, existem maneiras fáceis de passar informações ao controlador subserviente e recuperar as informações. O ARC simplifica a passagem de ponteiros para itens derivados de NSObjects; portanto, se você deseja que o controlador subserviente adicione / altere / modifique alguns dados, passe-o como ponteiro para uma instância mutável. Os blocos facilitam as ações de aprovação; portanto, se você deseja que o controlador subserviente invoque uma ação no seu controlador de nível superior, passe-o um bloco. Você define o bloco para aceitar qualquer número de argumentos que faça sentido para você. Você também pode projetar a API para usar vários blocos, se isso for melhor.
Aqui estão dois exemplos triviais da cola segue. O primeiro é direto, mostrando um parâmetro passado para entrada, o segundo para saída.
Este segundo exemplo mostra a passagem de um bloco de retorno de chamada para o segundo argumento. Eu gosto de usar blocos porque mantém os detalhes relevantes próximos na fonte - a fonte de nível superior.
fonte
Retornar dados do ViewController 2 (destino) para o viewController 1 (Origem) é a coisa mais interessante. Supondo que você use o storyBoard, essas são todas as maneiras que descobri:
Já foram discutidos aqui.
Eu descobri que existem mais maneiras:
-Usando retornos de chamada em bloco:
use-o no
prepareForSegue
método no VC1-Usando storyboards Descontrair (Sair)
Implemente um método com um argumento UIStoryboardSegue no VC 1, como este:
No storyBoard, ligue o botão "return" ao botão verde Exit (Unwind) do vc. Agora você tem uma sequência que "retorna" para que você possa usar a propriedade destinationViewController no prepareForSegue do VC2 e alterar qualquer propriedade do VC1 antes de voltar.
Outra opção do uso de storyboards Undwind (Exit) - você pode usar o método que escreveu no VC1
E no prepareForSegue do VC1, você pode alterar qualquer propriedade que deseja compartilhar.
Nas duas opções de desenrolamento, você pode definir a propriedade tag do botão e verificá-la no prepareForSegue.
Espero ter acrescentado algo à discussão.
:) Felicidades.
fonte
Existem vários métodos para compartilhar dados.
Você sempre pode compartilhar dados usando
NSUserDefaults
. Defina o valor que deseja compartilhar com relação a uma chave de sua escolha e obtenha o valorNSUserDefault
associado a essa chave no próximo controlador de exibição.Você pode apenas criar uma propriedade no
viewcontrollerA
. Crie um objeto deviewcontrollerA
inviewcontrollerB
e atribua o valor desejado a essa propriedade.Você também pode criar delegados personalizados para isso.
fonte
Se você deseja passar dados de um controlador para outro, tente este código
FirstViewController.h
SecondViewController.h
FirstViewController.m
fonte
Esta é uma resposta muito antiga e isso é antipadrão, use delegados. Não use essa abordagem !!
1. Crie a instância do primeiro View Controller no segundo View Controller e faça sua propriedade
@property (nonatomic,assign)
.2. Atribua a
SecondviewController
instância deste controlador de exibição.2. Ao concluir a operação de seleção, copie a matriz para o primeiro View Controller. Quando você descarrega o SecondView, o FirstView retém os dados da matriz.
Espero que isto ajude.
fonte
Eu estava pesquisando essa solução há muito tempo, encontrei-a pela Atlast. Primeiro, declare todos os objetos no seu arquivo SecondViewController.h como
Agora, no seu arquivo de implementação, aloque a memória para objetos como este
Agora você alocou a memória
Array
e o objeto. agora você pode preencher essa memória antes de pressionar esteViewController
Vá para o SecondViewController.he escreva dois métodos
no arquivo de implementação, você pode implementar a função
esperando que você
CustomObject
precise ter uma função setter com ele.agora seu trabalho básico está feito. vá para o local em que deseja empurrar
SecondViewController
e faça o seguinteTome cuidado com erros de ortografia.
fonte
Esta não é a maneira de fazer isso, você deve usar delegados, presumo que tenhamos dois controladores de exibição, ViewController1 e ViewController2, e essa coisa de verificação está no primeiro e, quando seu estado muda, você deseja fazer algo no ViewController2, para Para conseguir isso da maneira correta, faça o seguinte:
Adicione um novo arquivo ao seu projeto (Protocolo Objective-C) Arquivo -> Novo, agora chame-o de ViewController1Delegate ou o que você quiser e escreva-o entre as diretivas @interface e @end
Agora vá para ViewController2.he adicione
altere sua definição para
Agora vá para ViewController2.m e, dentro da implementação, adicione:
Agora vá para ViewController1.he adicione a seguinte propriedade:
Agora, se você estiver criando o ViewController1 dentro do ViewController2 após algum evento, faça o seguinte usando arquivos NIB:
Agora você está pronto, sempre que detectar o evento de verificação alterado no ViewController1, tudo o que você precisa fazer é o abaixo
Diga-me se há algo que não esteja claro se eu não entendi sua pergunta corretamente.
fonte
Se você deseja enviar dados de um para outro viewController, aqui está uma maneira de fazê-lo:
Digamos que temos viewControllers: viewControllerA e viewControllerB
Agora no viewControllerB.h
In viewControllerB.m
In viewControllerA.m
Portanto, é assim que você pode transmitir dados do viewControllerA para o viewControllerB sem definir nenhum representante. ;)
fonte
Sei que esse é um assunto muito comentado, mas para quem procura responder a essa pergunta com uma inclinação SWIFT e quer um exemplo básico, aqui está meu método para passar dados, se você estiver usando um segue para se locomover.
É semelhante ao anterior, mas sem os botões, etiquetas e outros. Simplesmente passando dados de uma visualização para a seguinte.
Configurar o Storyboard
Existem três partes.
Este é um layout de visualização muito simples, com um segue entre eles.
Aqui está a configuração para o remetente
Aqui está a configuração para o receptor.
Por fim, a configuração para o segue.
Os controladores de exibição
Estamos mantendo isso simples, para que não haja botões, nem ações; estamos simplesmente movendo dados do remetente para o receptor quando o aplicativo é carregado e, em seguida, emitindo o valor transmitido para o console.
Esta página pega o valor inicialmente carregado e o repassa.
Esta página apenas envia o valor da variável para o console quando ele é carregado. A essa altura, nosso filme favorito deve estar nessa variável.
É assim que você pode resolvê-lo se quiser usar um segue e não tiver suas páginas sob um controlador de navegação.
Uma vez executado, ele deve alternar para a visualização do receptor automaticamente e passar o valor do remetente para o receptor, exibindo o valor no console.
fonte
No meu caso, usei uma classe singleton que pode funcionar como um objeto global, permitindo o acesso aos dados de quase todos os lugares do aplicativo. A primeira coisa é construir uma classe singleton. Por favor, consulte a página “ Como deve ser meu singleton Objective-C? ” E o que eu fiz para tornar o objeto globalmente acessível foi simplesmente importá-lo
appName_Prefix.pch
para a aplicação da declaração de importação em todas as classes. Para acessar e usar esse objeto, simplesmente implementei o método de classe para retornar a instância compartilhada, que contém suas próprias variáveisfonte
Existem várias opções para passar dados entre os controladores de exibição.
Vou reescrever sua lógica no Swift com o último iOS Framework
Etapa 1. Declarar variável no ViewControllerB
Etapa 2. Variável de impressão no método ViewControllerB 'ViewDidLoad
Etapa 3. No ViewControllerA Pass Data enquanto pressiona através do Navigation Controller
Então, aqui está o código completo para:
ViewControllerA
ViewControllerB
Etapa 1. Crie um Segue de ViewControllerA para ViewControllerB e forneça Identifier = showDetailSegue no Storyboard, como mostrado abaixo
Etapa 2. No ViewControllerB Declare um viável chamado isSomethingEnabled e imprima seu valor.
Etapa 3. No ViewController, o valor de um passe isSomethingEnabled ao passar Segue
Então, aqui está o código completo para:
ViewControllerA
ViewControllerB
Etapa 1. Declarar o protocolo ViewControllerBDelegate no arquivo ViewControllerB, mas fora da classe
Etapa 2. Declare a instância da variável Delegate em ViewControllerB
Etapa 3. Envie dados para delegar dentro do método viewDidLoad do ViewControllerB
Etapa 4. Confirme o ViewControllerBDelegate no ViewControllerA
Etapa 5. Confirme que você implementará o delegado no ViewControllerA
Etapa 6. Implemente o método delegado para receber dados no ViewControllerA
Então, aqui está o código completo para:
ViewControllerA
ViewControllerB
Etapa 1. Defina e publique dados no observador de notificações no ViewControllerB
Etapa 2. Adicione o Notification Observer no ViewControllerA
Etapa 3. Receba o valor dos dados de notificação no ViewControllerA
Então, aqui está o código completo para:
ViewControllerA
ViewControllerB
Etapa 1. Declarar o bloco no ViewControllerB
var authorCompletionBlock: ((Bool) -> ())? = {_ in}
Etapa 2. Defina os dados no bloco no ViewControllerB
Etapa 3. Receba os dados do bloco no ViewControllerA
Então, aqui está o código completo para:
ViewControllerA
ViewControllerB
Você pode encontrar uma amostra completa do aplicativo no meu GitHub. Informe-me se tiver alguma dúvida sobre isso.
fonte
Passando dados entre o FirstViewController para o SecondViewController como abaixo
Por exemplo:
FirstViewController Valor da string como
para que possamos passar esse valor na segunda classe usando o passo abaixo
1> Precisamos criar um objeto string no arquivo SecondViewController.h
2> Precisa declarar a propriedade conforme abaixo abaixo na declaração no arquivo .h
3> Precisa sintetizar esse valor no arquivo FirstViewController.m abaixo da declaração do cabeçalho
e no FirstViewController.h:
4> No FirstViewController, em qual método navegamos para a segunda visualização, escreva o código abaixo nesse método.
fonte
Atualmente, estou contribuindo para uma solução de código aberto para esse problema através de um projeto chamado MCViewFactory, que pode ser encontrado aqui:
https://github.com/YetiHQ/manticore-iosviewfactory
A idéia é imitar o paradigma de intenções do Android, usando uma fábrica global para gerenciar qual visualização você está visualizando e usando "intenções" para alternar e passar dados entre as exibições. Toda a documentação está na página do github, mas aqui estão alguns destaques:
Você configura todas as suas visualizações em arquivos .XIB e as registra no delegado do aplicativo enquanto inicializa a fábrica.
Agora, no seu VC, sempre que você desejar mover para um novo VC e transmitir dados, crie uma nova intenção e adicione dados ao seu dicionário (savedInstanceState). Em seguida, basta definir a intenção atual da fábrica:
Todas as suas visualizações que estão em conformidade com isso precisam ser subclasses do MCViewController, que permitem substituir o novo método onResume:, permitindo acessar os dados que você transmitiu.
Espero que alguns de vocês achem esta solução útil / interessante.
fonte
Crie a propriedade no próximo
view controller .h
e defina getter e setter.Adicione isso
property
no NextVC.h no nextVCAdicionar
@synthesize indexNumber;
no NextVC.mE por ultimo
fonte
Existem várias maneiras de fazer isso e é importante escolher a correta. Provavelmente, uma das maiores decisões de arquitetura reside em como o código do modelo será compartilhado ou acessado em todo o aplicativo.
Eu escrevi um post sobre isso há algum tempo: Compartilhando o Código do Modelo . Aqui está um breve resumo:
Dados compartilhados
Uma abordagem é compartilhar ponteiros para os objetos de modelo entre os controladores de exibição.
Como preparar para segue é o mais comum, aqui está um exemplo:
Acesso independente
Outra abordagem é lidar com uma tela cheia de dados de cada vez e, em vez de acoplar os controladores de exibição, acoplar cada controlador de exibição à única fonte de dados que eles podem acessar independentemente.
A maneira mais comum de fazer isso é uma instância singleton . Portanto, se o seu objeto singleton fosse,
DataAccess
você poderia fazer o seguinte no método viewDidLoad do UIViewController:Existem ferramentas adicionais que também ajudam a transmitir dados:
Dados principais
O bom do Core Data é que ele tem relacionamentos inversos. Portanto, se você quiser apenas fornecer ao NotesViewController o objeto notes, você poderá, porque ele terá um relacionamento inverso com algo mais como o notebook. Se você precisar de dados no bloco de notas no NotesViewController, poderá voltar ao gráfico de objetos fazendo o seguinte:
Leia mais sobre isso no meu blog: Compartilhando código de modelo
fonte
NewsViewController
NewsDetailViewController.h
NewsDetailViewController.m
fonte
A delegação é a única solução para executar essas operações quando você estiver usando arquivos .xib. No entanto, todas as respostas descritas acima são para
storyboard
arquivos .xibs que você precisa para usar a delegação. essa é a única solução que você pode.Outra solução é usar o padrão de classe singleton para inicializá-lo uma vez e usá-lo em todo o aplicativo.
fonte
Se você deseja passar dados do ViewControlerOne para o ViewController, tente estes dois ..
faça isso em ViewControlerOne.h
faça isso em ViewControllerTwo.h
Sintetizar str2 em ViewControllerTwo.m
faça isso em ViewControlerOne.m
nos botões, clique em evento, faça isso.
faça isso em ViewControllerTwo.m
fonte
Você pode salvar os dados no aplicativo delegado para acessá-los nos controladores de exibição do seu aplicativo. Tudo o que você precisa fazer é criar uma instância compartilhada do delegado do aplicativo
Por exemplo
se você declarar um
NSArray object *arrayXYZ
, poderá acessá-lo em qualquer controlador de exibiçãoappDelegate.arrayXYZ
fonte
Se você deseja enviar dados de um para outro viewController, aqui está uma maneira de fazê-lo:
Digamos que temos viewControllers: ViewController e NewViewController.
em ViewController.h
em ViewController.m
Em NewViewController.h
Em NewViewController.m
Desta forma, podemos passar os dados de um viewcontroller para outro view controller ...
fonte
Gosto da idéia dos objetos Modelo e Mock baseados no NSProxy para confirmar ou descartar dados, se o usuário selecionar puder ser cancelado.
É fácil transmitir dados, já que é um único objeto ou alguns objetos e, se você digitar o controlador UINavigationController, pode manter a referência do modelo dentro e todos os controladores de exibição por push podem acessá-lo diretamente do controlador de navegação.
fonte
Eu já vi muitas pessoas complicando isso usando o
didSelectRowAtPath
método Estou usando o Core Data no meu exemplo.4 linhas de código dentro do método e pronto.
fonte
Existem muitas respostas para essas perguntas, oferecendo muitas maneiras diferentes de executar a comunicação do controlador de exibição que de fato funcionaria, mas não vejo em nenhum lugar mencionado qual é realmente o melhor para usar e quais evitar.
Na prática, na minha opinião, apenas algumas soluções são recomendadas:
prepare(for:sender:)
métodoUIViewController
ao usar um storyboard e seguesSoluções que eu recomendo NÃO usar:
Essas soluções, embora funcionem a curto prazo, introduzem muitas dependências que distorcem a arquitetura do aplicativo e criam mais problemas posteriormente.
Para os interessados, escrevi alguns artigos que abordam esses pontos com mais profundidade e destacam as várias desvantagens:
fonte