Cette question semble être très populaire ici sur stackoverflow, alors j'ai pensé que j'essaierais de donner une meilleure réponse pour aider les gens qui commencent dans le monde d'iOS comme moi.
J'espère que cette réponse est suffisamment claire pour que les gens comprennent et que je n'ai rien manqué.
Transmission des données vers l'avant
Transmission de données à un contrôleur de vue à partir d'un autre contrôleur de vue. Vous utiliseriez cette méthode si vous vouliez passer un objet / une valeur d'un contrôleur de vue à un autre contrôleur de vue que vous pourriez pousser sur une pile de navigation.
Pour cet exemple, nous aurons ViewControllerA
etViewControllerB
Pour passer une BOOL
valeur de ViewControllerA
à ViewControllerB
nous ferions ce qui suit.
pour ViewControllerB.h
créer une propriété pour leBOOL
@property (nonatomic, assign) BOOL isSomethingEnabled;
en ViewControllerA
vous devez en parler ViewControllerB
alors utilisez un
#import "ViewControllerB.h"
Ensuite, où vous souhaitez charger la vue par exemple. didSelectRowAtIndex
ou certains dont IBAction
vous avez besoin pour définir la propriété ViewControllerB
avant de la pousser sur la pile de navigation.
ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
viewControllerB.isSomethingEnabled = YES;
[self pushViewController:viewControllerB animated:YES];
Cela mis isSomethingEnabled
à ViewControllerB
la BOOL
valeur YES
.
Transmission de données à l'aide de Segues
Si vous utilisez des storyboards, vous utilisez probablement des séquences et aurez besoin de cette procédure pour transmettre les données. Ceci est similaire à ce qui précède, mais au lieu de transmettre les données avant de pousser le contrôleur de vue, vous utilisez une méthode appelée
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
Donc , pour passer un BOOL
de ViewControllerA
à ViewControllerB
nous faire ce qui suit:
pour ViewControllerB.h
créer une propriété pour leBOOL
@property (nonatomic, assign) BOOL isSomethingEnabled;
en ViewControllerA
vous devez en parler ViewControllerB
alors utilisez un
#import "ViewControllerB.h"
Créez un enchaînement de ViewControllerA
à ViewControllerB
sur le storyboard et donnez-lui un identifiant, dans cet exemple, nous l'appellerons"showDetailSegue"
Ensuite, nous devons ajouter la méthode à ViewControllerA
celle qui est appelée quand une séquence est effectuée, à cause de cela, nous devons détecter quelle séquence a été appelée et ensuite faire quelque chose. Dans notre exemple, nous vérifierons "showDetailSegue"
et si cela est effectué, nous transmettrons notre BOOL
valeur àViewControllerB
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:@"showDetailSegue"]){
ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController;
controller.isSomethingEnabled = YES;
}
}
Si vos vues sont intégrées dans un contrôleur de navigation, vous devez modifier légèrement la méthode ci-dessus comme suit
-(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;
}
}
Cela mis isSomethingEnabled
à ViewControllerB
la BOOL
valeur YES
.
Transmission de données
Pour retransmettre des données de ViewControllerB
à ViewControllerA
vous devez utiliser des protocoles et des délégués ou des blocs , ces derniers peuvent être utilisés comme un mécanisme à couplage lâche pour les rappels.
Pour ce faire, nous ferons ViewControllerA
un délégué de ViewControllerB
. Cela permet ViewControllerB
de renvoyer un message pour ViewControllerA
nous permettre de renvoyer des données.
Pour ViewControllerA
en être délégué, ViewControllerB
il faut se conformer au ViewControllerB
protocole que nous devons préciser. Cela indique ViewControllerA
quelles méthodes il doit implémenter.
Dans ViewControllerB.h
, en dessous de #import
, mais au-dessus, @interface
vous spécifiez le protocole.
@class ViewControllerB;
@protocol ViewControllerBDelegate <NSObject>
- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
@end
ensuite toujours dans le dont ViewControllerB.h
vous avez besoin pour configurer une delegate
propriété et synthétiser dansViewControllerB.m
@property (nonatomic, weak) id <ViewControllerBDelegate> delegate;
Dans ViewControllerB
nous appelons un message delegate
lorsque nous ouvrons le contrôleur de vue.
NSString *itemToPassBack = @"Pass this value back to ViewControllerA";
[self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];
C'est tout ViewControllerB
. Maintenant ViewControllerA.h
, dites ViewControllerA
d'importer ViewControllerB
et de vous conformer à son protocole.
#import "ViewControllerB.h"
@interface ViewControllerA : UIViewController <ViewControllerBDelegate>
En ViewControllerA.m
implémentant la méthode suivante de notre protocole
- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item
{
NSLog(@"This was returned from ViewControllerB %@",item);
}
Avant de pousser viewControllerB
vers la pile de navigation, nous devons dire ViewControllerB
que ViewControllerA
c'est son délégué, sinon nous obtiendrons une erreur.
ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
viewControllerB.delegate = self
[[self navigationController] pushViewController:viewControllerB animated:YES];
Références
- Utilisation de la délégation pour communiquer avec d'autres contrôleurs de vue dans le Guide de programmation du contrôleur de vue
- Modèle de délégué
NSNotification center
C'est une autre façon de transmettre des données.
// 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];
Transmission de données d'une classe à une autre (une classe peut être n'importe quel contrôleur, gestionnaire de réseau / session, sous-classe UIView ou toute autre classe)
Les blocs sont des fonctions anonymes.
Cet exemple transmet les données du contrôleur B au contrôleur A
définir un bloc
@property void(^selectedVoucherBlock)(NSString *); // in ContollerA.h
ajouter un gestionnaire de blocs (écouteur)
là où vous avez besoin d'une valeur (par exemple, vous avez besoin de votre réponse API dans ControllerA ou vous avez besoin de données ContorllerB sur A)
// in ContollerA.m
- (void)viewDidLoad {
[super viewDidLoad];
__unsafe_unretained typeof(self) weakSelf = self;
self.selectedVoucherBlock = ^(NSString *voucher) {
weakSelf->someLabel.text = voucher;
};
}
Aller au contrôleur B
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ControllerB *vc = [storyboard instantiateViewControllerWithIdentifier:@"ControllerB"];
vc.sourceVC = self;
[self.navigationController pushViewController:vc animated:NO];
coupe-feu
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath {
NSString *voucher = vouchersArray[indexPath.row];
if (sourceVC.selectVoucherBlock) {
sourceVC.selectVoucherBlock(voucher);
}
[self.navigationController popToViewController:sourceVC animated:YES];
}
Un autre exemple de travail pour les blocs
@class ViewControllerB;
au-dessus de la définition @protocol? Sans cela, j'obtiens une erreur "Type attendu" sur ViewControllerB dans la ligne:- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
dans la@protocol
déclarationNavigationController
vous devez utiliser à la[self.navigationController pushViewController:viewController animated:YES];
place[self pushViewController:viewControllerB animated:YES];
Rapide
Il y a des tonnes et des tonnes d'explications ici et autour de StackOverflow, mais si vous êtes un débutant qui essaie simplement de faire fonctionner quelque chose de basique, essayez de regarder ce tutoriel YouTube (c'est ce qui m'a aidé à enfin comprendre comment le faire).
Transmission des données au prochain View Controller
Voici un exemple basé sur la vidéo. L'idée est de passer une chaîne du champ de texte du First View Controller à l'étiquette du Second View Controller.
Créez la disposition du storyboard dans le générateur d'interface. Pour effectuer la séquence, il vous suffit de Controlcliquer sur le bouton et de le faire glisser vers le deuxième contrôleur de vue.
Contrôleur First View
Le code du First View Controller est
Second View Controller
Et le code du Second View Controller est
N'oublie pas
UITextField
et leUILabel
.Retour des données au précédent View Controller
Pour renvoyer des données du deuxième contrôleur de vue au premier contrôleur de vue, vous utilisez un protocole et un délégué . Cette vidéo est un aperçu très clair de ce processus:
Voici un exemple basé sur la vidéo (avec quelques modifications).
Créez la disposition du storyboard dans le générateur d'interface. Encore une fois, pour faire la séquence, il vous suffit de Controlfaire glisser le bouton vers le deuxième contrôleur de vue. Définissez l'identifiant de séquence sur
showSecondViewController
. N'oubliez pas non plus de connecter les sorties et les actions en utilisant les noms dans le code suivant.Contrôleur First View
Le code du First View Controller est
Notez l'utilisation de notre
DataEnteredDelegate
protocole personnalisé .Contrôleur et protocole Second View
Le code du deuxième contrôleur de vue est
Notez que le
protocol
est en dehors de la classe View Controller.C'est ça. En exécutant l'application maintenant, vous devriez pouvoir renvoyer des données du deuxième contrôleur de vue au premier.
la source
secondViewController.delegate = self
signifie «J'accepte d'être le travailleur du patron». Voir cette réponse pour un autre exemple et plus d'explications.Le M dans MVC est pour "Model" et dans le paradigme MVC le rôle des classes de modèle est de gérer les données d'un programme. Un modèle est l'opposé d'une vue - une vue sait comment afficher des données, mais elle ne sait pas quoi faire des données, tandis qu'un modèle sait tout comment travailler avec des données, mais rien comment les afficher. Les modèles peuvent être compliqués, mais ils ne doivent pas l'être - le modèle de votre application peut être aussi simple qu'un tableau de chaînes ou de dictionnaires.
Le rôle d'un contrôleur est de servir de médiateur entre la vue et le modèle. Par conséquent, ils ont besoin d'une référence à un ou plusieurs objets de vue et à un ou plusieurs objets de modèle. Disons que votre modèle est un tableau de dictionnaires, chaque dictionnaire représentant une ligne de votre tableau. La vue racine de votre application affiche cette table et il peut être responsable du chargement du tableau à partir d'un fichier. Lorsque l'utilisateur décide d'ajouter une nouvelle ligne à la table, il appuie sur un bouton et votre contrôleur crée un nouveau dictionnaire (modifiable) et l'ajoute au tableau. Afin de remplir la ligne, le contrôleur crée un contrôleur de vue de détail et lui donne le nouveau dictionnaire. Le contrôleur de vue détaillée remplit le dictionnaire et revient. Le dictionnaire fait déjà partie du modèle, donc rien d'autre ne doit se produire.
la source
Il existe différentes manières de recevoir des données vers une autre classe dans iOS. Par exemple -
NSUserDefaults
- pour y accéder plus tardMais pour le scénario simple consistant à transmettre une valeur à une classe différente dont l'allocation est effectuée dans la classe actuelle, la méthode la plus courante et préférée serait la définition directe des valeurs après l'allocation. Cela se fait comme suit:-
Nous pouvons le comprendre en utilisant deux contrôleurs - Controller1 et Controller2
Supposons que dans la classe Controller1, vous souhaitez créer l'objet Controller2 et le pousser avec une valeur String transmise. Cela peut être fait comme ceci: -
Dans la mise en œuvre de la classe Controller2, il y aura cette fonction
Vous pouvez également définir directement les propriétés de la classe Controller2 de la même manière que ceci:
Pour passer plusieurs valeurs, vous pouvez utiliser les paramètres multiples comme: -
Ou si vous devez transmettre plus de 3 paramètres liés à une fonction commune, vous pouvez stocker les valeurs dans une classe Model et transmettre ce modelObject à la classe suivante
Bref, si vous voulez -
J'espère que cela t'aides
la source
Après plus de recherches, il semble que Protocoles et Délégués soit la manière correcte / préférée d'Apple de le faire.
J'ai fini par utiliser cet exemple
Partage de données entre les contrôleurs de vue et d'autres objets @ SDK de développement iPhone
A très bien fonctionné et m'a permis de passer une chaîne et un tableau en avant et en arrière entre mes vues.
Merci pour votre aide
la source
Je trouve la version la plus simple et la plus élégante avec des blocs qui passent. Appelons le contrôleur de vue qui attend les données renvoyées comme "A" et le contrôleur de vue qui le renvoie comme "B". Dans cet exemple, nous voulons obtenir 2 valeurs: la première de Type1 et la seconde de Type2.
En supposant que nous utilisons Storyboard, le premier contrôleur définit le bloc de rappel, par exemple lors de la préparation de la séquence:
et le contrôleur de vue "B" doit déclarer la propriété de rappel, BViewController.h:
Que dans le fichier d'implémentation BViewController.m après que nous ayons souhaité que les valeurs renvoyées, notre rappel soit appelé:
Une chose à retenir est que l'utilisation du bloc nécessite souvent de gérer des références fortes et __ faibles comme expliqué ici
la source
La plupart des réponses données contiennent de bonnes informations, mais aucune ne répond pleinement à la question.
La question porte sur la transmission d'informations entre les contrôleurs de vue. L'exemple spécifique donné concerne la transmission d'informations entre les vues, mais compte tenu de la nouveauté auto-déclarée d'iOS, l'affiche originale signifiait probablement entre les viewControllers, pas entre les vues (sans aucune implication des ViewControllers). Il semble que toutes les réponses se concentrent sur deux contrôleurs de vue, mais que faire si l'application évolue pour impliquer plus de deux contrôleurs de vue dans l'échange d'informations?
L'affiche originale a également posé des questions sur les singletons et l'utilisation de l' AppDelegate . Il faut répondre à ces questions.
Pour aider quiconque qui regarde cette question et qui veut une réponse complète, je vais essayer de la fournir.
Scénarios d'application
Plutôt que d'avoir une discussion abstraite hautement hypothétique, il est utile d'avoir à l'esprit des applications concrètes. Pour aider à définir une situation de contrôleur à deux vues et une situation de contrôleur à plus de deux vues, je vais définir deux scénarios d'application concrets.
Scénario 1: deux contrôleurs de vue au maximum doivent partager des informations. Voir schéma un.
Il existe deux contrôleurs de vue dans l'application. Il existe un ViewControllerA (formulaire de saisie de données) et View Controller B (liste de produits). Les éléments sélectionnés dans la liste de produits doivent correspondre aux éléments affichés dans la zone de texte du formulaire de saisie de données. Dans ce scénario, ViewControllerA et ViewControllerB doivent communiquer directement entre eux et aucun autre contrôleur de vue.
Scénario deux : plus de deux contrôleurs de vue doivent partager les mêmes informations. Voir le diagramme deux.
Il y a quatre contrôleurs de vue dans l'application. Il s'agit d'une application basée sur des onglets pour gérer l'inventaire des maisons. Trois contrôleurs de vue présentent des vues filtrées différemment des mêmes données:
Chaque fois qu'un élément individuel est créé ou modifié, il doit également se synchroniser avec les autres contrôleurs de vue. Par exemple, si nous ajoutons un bateau dans ViewControllerD, mais qu'il n'est pas encore assuré, le bateau doit apparaître lorsque l'utilisateur accède à ViewControllerA (articles de luxe), ainsi qu'à ViewControllerC (inventaire de toute la maison), mais pas lorsque l'utilisateur accède à ViewControllerB (Articles non assurés). Nous devons nous préoccuper non seulement d'ajouter de nouveaux éléments, mais également de supprimer des éléments (qui peuvent être autorisés à partir de n'importe lequel des quatre contrôleurs de vue), ou de modifier des éléments existants (qui peuvent être autorisés à partir du "Ajouter un nouveau formulaire d'élément", en réaffectant le même pour l'édition).
Étant donné que tous les contrôleurs de vue doivent partager les mêmes données, les quatre contrôleurs de vue doivent rester synchronisés, et il doit donc y avoir une sorte de communication avec tous les autres contrôleurs de vue, chaque fois qu'un seul contrôleur de vue modifie les données sous-jacentes. Il devrait être assez évident que nous ne voulons pas que chaque contrôleur de vue communique directement entre eux dans ce scénario. Dans le cas où ce n'est pas évident, considérez si nous avions 20 contrôleurs de vue différents (plutôt que seulement 4). Dans quelle mesure serait-il difficile et sujet à erreurs de notifier chacun des 19 autres contrôleurs de vue chaque fois qu'un contrôleur de vue effectuait un changement?
Les solutions: les délégués et le modèle d'observateur, et les singletons
Dans le scénario un, nous avons plusieurs solutions viables, comme d'autres réponses ont donné
Dans le scénario deux, nous avons d'autres solutions viables:
Un singleton est une instance d'une classe, cette instance étant la seule instance existant au cours de sa durée de vie. Un singleton tire son nom du fait qu'il s'agit de l'instance unique. Normalement, les développeurs qui utilisent des singletons ont des méthodes de classe spéciales pour y accéder.
Maintenant que nous comprenons ce qu'est un singleton, voyons comment un singleton s'intègre dans le modèle d'observateur. Le motif d'observateur est utilisé pour qu'un objet réponde aux changements d'un autre objet. Dans le deuxième scénario, nous avons quatre contrôleurs de vue différents, qui veulent tous être informés des modifications apportées aux données sous-jacentes. Les "données sous-jacentes" doivent appartenir à une seule instance, un singleton. Le "savoir sur les changements" est accompli en observant les changements apportés au singleton.
L'application d'inventaire d'origine aurait une seule instance d'une classe conçue pour gérer une liste d'articles d'inventaire. Le gestionnaire gérerait une collection d'articles ménagers. Voici une définition de classe pour le gestionnaire de données:
Lorsque la collection d'articles d'inventaire d'origine change, les contrôleurs de vue doivent être informés de cette modification. La définition de classe ci-dessus ne rend pas évident comment cela se produira. Nous devons suivre le modèle de l'observateur. Les contrôleurs de vue doivent observer formellement le sharedManager. Il existe deux façons d'observer un autre objet:
Dans le scénario deux, nous n'avons pas une seule propriété de HouseholdInventoryManager qui pourrait être observée à l'aide de KVO. Parce que nous n'avons pas une seule propriété facilement observable, le modèle d'observateur, dans ce cas, doit être implémenté à l'aide de NSNotificationCenter. Chacun des quatre contrôleurs de vue souscrirait aux notifications et le sharedManager enverrait des notifications au centre de notifications, le cas échéant. Le gestionnaire d'inventaire n'a pas besoin de savoir quoi que ce soit sur les contrôleurs de vue ou les instances d'autres classes qui pourraient être intéressés de savoir quand la collection d'articles d'inventaire change; NSNotificationCenter s'occupe de ces détails d'implémentation. Les contrôleurs de vue s'abonnent simplement aux notifications et le gestionnaire de données publie simplement les notifications.
De nombreux programmeurs débutants profitent du fait qu'il y a toujours exactement un délégué d'application dans la durée de vie de l'application, ce qui est globalement accessible. Les programmeurs débutants utilisent ce fait pour bourrer des objets et des fonctionnalités dans appDelegate pour faciliter l'accès à partir de n'importe où ailleurs dans l'application. Ce n'est pas parce que AppDelegate est un singleton qu'il doit remplacer tous les autres singletons. C'est une mauvaise pratique car elle impose trop de charge à une classe, ce qui brise les bonnes pratiques orientées objet. Chaque classe doit avoir un rôle clair qui s'explique facilement, souvent simplement par le nom de la classe.
Chaque fois que votre délégué d'application commence à se gonfler, commencez à supprimer les fonctionnalités des singletons. Par exemple, la pile de données principale ne doit pas être laissée dans AppDelegate, mais doit plutôt être placée dans sa propre classe, une classe coreDataManager.
Références
la source
L'OP ne mentionnait pas les contrôleurs de vue, mais tant de réponses le font, que je voulais répondre à ce que certaines des nouvelles fonctionnalités de la LLVM permettent de rendre plus facile lorsque vous souhaitez transmettre des données d'un contrôleur de vue à un autre, puis obtenir des résultats.
Les séquences de storyboard, les blocs ARC et LLVM rendent cela plus facile que jamais pour moi. Certaines réponses ci-dessus mentionnaient déjà des scénarios et des séquences, mais reposaient toujours sur la délégation. Définir des délégués fonctionne certainement, mais certaines personnes peuvent trouver plus facile de passer des pointeurs ou des blocs de code.
Avec UINavigators et segues, il existe des moyens faciles de transmettre des informations au contrôleur secondaire et de récupérer les informations. ARC facilite le passage de pointeurs vers des éléments dérivés de NSObjects. Si vous souhaitez que le contrôleur subservient ajoute / change / modifie des données pour vous, passez-lui un pointeur vers une instance mutable. Les blocs facilitent le passage des actions, donc si vous voulez que le contrôleur subordonné invoque une action sur votre contrôleur de niveau supérieur, passez-lui un bloc. Vous définissez le bloc pour accepter n'importe quel nombre d'arguments qui vous conviennent. Vous pouvez également concevoir l'API pour utiliser plusieurs blocs si cela convient mieux.
Voici deux exemples triviaux de la colle segue. Le premier montre simplement un paramètre passé pour l'entrée, le second pour la sortie.
Ce deuxième exemple montre comment passer un bloc de rappel pour le deuxième argument. J'aime utiliser des blocs car il garde les détails pertinents proches les uns des autres dans la source - la source de niveau supérieur.
la source
La transmission de données de ViewController 2 (destination) à viewController 1 (Source) est la chose la plus intéressante. En supposant que vous utilisez storyBoard, voici toutes les façons dont j'ai découvert:
Celles-ci ont déjà été discutées ici.
J'ai trouvé qu'il y avait plus de façons:
-Utilisation des rappels de bloc:
l'utiliser dans la
prepareForSegue
méthode du VC1-Utilisation de storyboards Unwind (Quitter)
Implémentez une méthode avec un argument UIStoryboardSegue dans VC 1, comme celui-ci:
Dans le StoryBoard, accrochez le bouton "retour" au bouton vert de sortie (déroulement) du vc. Maintenant, vous avez une séquence qui "remonte" afin que vous puissiez utiliser la propriété destinationViewController dans prepareForSegue de VC2 et modifier n'importe quelle propriété de VC1 avant qu'elle ne revienne.
Une autre option d'utilisation des storyboards Undwind (Exit) - vous pouvez utiliser la méthode que vous avez écrite dans VC1
Et dans le prepareForSegue de VC1, vous pouvez modifier n'importe quelle propriété que vous souhaitez partager.
Dans les deux options de déroulement, vous pouvez définir la propriété de balise du bouton et la vérifier dans prepareForSegue.
J'espère que j'ai ajouté quelque chose à la discussion.
:) À votre santé.
la source
Il existe plusieurs méthodes pour partager des données.
Vous pouvez toujours partager des données à l'aide de
NSUserDefaults
. Définissez la valeur que vous souhaitez partager par rapport à une clé de votre choix et obtenez la valeurNSUserDefault
associée à cette clé dans le prochain contrôleur de vue.Vous pouvez simplement créer une propriété dans
viewcontrollerA
. Créez un objet deviewcontrollerA
inviewcontrollerB
et affectez la valeur souhaitée à cette propriété.Vous pouvez également créer des délégués personnalisés pour cela.
la source
Si vous souhaitez transmettre des données d'un contrôleur à un autre, essayez ce code
FirstViewController.h
SecondViewController.h
FirstViewController.m
la source
Ceci est une réponse très ancienne et anti-modèle, veuillez utiliser des délégués. N'utilisez pas cette approche !!
1. Créez l'instance du premier View Controller dans le second View Controller et définissez sa propriété
@property (nonatomic,assign)
.2. Attribuez l'
SecondviewController
instance de ce contrôleur de vue.2. Lorsque vous avez terminé l'opération de sélection, copiez la matrice sur le premier contrôleur de vue. Lorsque vous déchargez SecondView, FirstView contiendra les données de la matrice.
J'espère que cela t'aides.
la source
Je cherchais cette solution depuis longtemps, Atlast je l'ai trouvée. Tout d'abord, déclarez tous les objets de votre fichier SecondViewController.h comme
Maintenant, dans votre fichier d'implémentation, allouez la mémoire pour ces objets comme celui-ci
Vous avez maintenant alloué la mémoire
Array
et l'objet. vous pouvez maintenant remplir cette mémoire avant de pousserViewController
Accédez à votre SecondViewController.h et écrivez deux méthodes
dans le fichier d'implémentation, vous pouvez implémenter la fonction
en attendant que vous
CustomObject
deviez avoir une fonction setter avec elle.maintenant votre travail de base est terminé. allez à l'endroit où vous voulez pousser
SecondViewController
et faites les choses suivantesFaites attention aux fautes d'orthographe.
la source
Ce n'est pas la façon de le faire, vous devez utiliser des délégués, je suppose que nous avons deux contrôleurs de vue ViewController1 et ViewController2 et cette vérification est dans la première et lorsque son état change, vous voulez faire quelque chose dans ViewController2, pour Pour y parvenir correctement, vous devez procéder comme suit:
Ajoutez un nouveau fichier à votre projet (protocole Objective-C) Fichier -> Nouveau, nommez-le maintenant ViewController1Delegate ou tout ce que vous voulez et écrivez-les entre les directives @interface et @end
Accédez maintenant à ViewController2.h et ajoutez
puis changez sa définition en
Allez maintenant à ViewController2.m et à l'intérieur de l'implémentation ajoutez:
Accédez maintenant à ViewController1.h et ajoutez la propriété suivante:
Maintenant, si vous créez ViewController1 dans ViewController2 après un événement, vous devez le faire de cette façon en utilisant des fichiers NIB:
Maintenant, vous êtes prêt, chaque fois que vous détectez que l’événement de vérification a changé dans ViewController1, tout ce que vous avez à faire est le suivant
Veuillez me dire s'il y a quelque chose qui n'est pas clair si je n'ai pas bien compris votre question.
la source
Si vous souhaitez envoyer des données de l'un à l'autre viewController, voici une façon de procéder:
Disons que nous avons viewControllers: viewControllerA et viewControllerB
Maintenant dans viewControllerB.h
In viewControllerB.m
In viewControllerA.m
C'est ainsi que vous pouvez transmettre des données de viewControllerA à viewControllerB sans définir de délégué. ;)
la source
Je sais que c'est un sujet battu mais pour ceux qui cherchent à répondre à cette question avec une pente SWIFT et veulent un exemple à nu, voici ma méthode de référence pour transmettre des données si vous utilisez un enchaînement pour vous déplacer.
Il est similaire à ce qui précède mais sans les boutons, les étiquettes et autres. Passer simplement les données d'une vue à l'autre.
Configurer le storyboard
Il y a trois parties.
Il s'agit d'une disposition de vue très simple avec une séquence entre eux.
Voici la configuration pour l'expéditeur
Voici la configuration du récepteur.
Enfin, la configuration de la séquence.
Les contrôleurs de vue
Nous gardons cela simple, donc pas de boutons, pas d'actions, nous déplaçons simplement les données de l'expéditeur vers le récepteur lorsque l'application se charge, puis la sortie de la valeur transmise vers la console.
Cette page prend la valeur initialement chargée et la transmet.
Cette page envoie simplement la valeur de la variable à la console lors de son chargement. À ce stade, notre film préféré devrait être dans cette variable.
Voilà comment vous pouvez y remédier si vous souhaitez utiliser un enchaînement et que vous n'avez pas vos pages sous un contrôleur de navigation.
Une fois exécuté, il doit passer automatiquement à la vue du récepteur et transmettre la valeur de l'expéditeur au récepteur, en affichant la valeur dans la console.
la source
Dans mon cas, j'ai utilisé une classe singleton qui peut fonctionner comme un objet global permettant d'accéder aux données de presque partout dans l'application. La première chose est de construire une classe singleton. S'il vous plaît se référer à la page « Que dois - je Objective-C singleton ressembler? » Et ce que je faisais simplement de faire l'objet était globalement accessible importer dans ce
appName_Prefix.pch
qui est d'appliquer la déclaration d'importation dans toutes les classes. Pour accéder à cet objet et l'utiliser, j'ai simplement implémenté une méthode de classe pour retourner l'instance partagée, qui contient ses propres variablesla source
Il existe plusieurs options pour transmettre des données entre les contrôleurs de vue.
Je vais réécrire sa logique dans Swift avec le dernier framework iOS
Étape 1. Déclarez la variable dans ViewControllerB
Étape 2. Imprimer la variable dans la méthode ViewDidLoad de ViewControllerB
Étape 3. Dans ViewControllerA Pass Data tout en poussant à travers le contrôleur de navigation
Voici donc le code complet pour:
ViewControllerA
ViewControllerB
Étape 1. Créez Segue de ViewControllerA à ViewControllerB et donnez Identifier = showDetailSegue dans Storyboard comme indiqué ci-dessous
Étape 2. Dans ViewControllerB, déclarez un isSomethingEnabled viable nommé et imprimer sa valeur.
Étape 3. Dans ViewControllerA, la valeur de isSomethingEnabled lors de la transmission de Segue
Voici donc le code complet pour:
ViewControllerA
ViewControllerB
Étape 1. Déclarez le protocole ViewControllerBDelegate dans le fichier ViewControllerB mais en dehors de la classe
Étape 2. Déclarez l'instance de variable Délégué dans ViewControllerB
Étape 3. Envoyer des données pour le délégué à l'intérieur de la méthode viewDidLoad de ViewControllerB
Étape 4. Confirmez ViewControllerBDelegate dans ViewControllerA
Étape 5. Confirmez que vous implémenterez délégué dans ViewControllerA
Étape 6. Implémentez la méthode déléguée pour recevoir des données dans ViewControllerA
Voici donc le code complet pour:
ViewControllerA
ViewControllerB
Étape 1. Définir et publier des données dans Notification Observer dans ViewControllerB
Étape 2. Ajouter un observateur de notifications dans ViewControllerA
Étape 3. Recevoir la valeur des données de notification dans ViewControllerA
Voici donc le code complet pour:
ViewControllerA
ViewControllerB
Étape 1. Déclarez le bloc dans ViewControllerB
var autorisationCompletionBlock: ((Bool) -> ())? = {_ in}
Étape 2. Définissez les données en bloc dans ViewControllerB
Étape 3. Recevoir des données de bloc dans ViewControllerA
Voici donc le code complet pour:
ViewControllerA
ViewControllerB
Vous pouvez trouver un exemple complet d'application sur mon GitHub Veuillez me faire savoir si vous avez des questions à ce sujet.
la source
Passage de données entre FirstViewController à SecondViewController comme ci-dessous
Par exemple:
FirstViewController Valeur de chaîne en tant que
afin que nous puissions passer cette valeur en deuxième classe en utilisant l'étape ci-dessous
1> Nous devons créer un objet chaîne dans le fichier SecondViewController.h
2> Besoin de déclarer la propriété comme ci-dessous la déclaration dans le fichier .h
3> Besoin de synthétiser cette valeur dans le fichier FirstViewController.m sous la déclaration d'en-tête
et dans FirstViewController.h:
4> Dans FirstViewController, à partir de quelle méthode nous accédons à la deuxième vue, veuillez écrire le code ci-dessous dans cette méthode.
la source
Je contribue actuellement à une solution open source à ce problème via un projet appelé MCViewFactory, qui peut être trouvé ici:
https://github.com/YetiHQ/manticore-iosviewfactory
L'idée est d'imiter le paradigme d'intention d'Android, en utilisant une usine globale pour gérer la vue que vous regardez et en utilisant des «intentions» pour basculer et transmettre des données entre les vues. Toute la documentation est sur la page github, mais voici quelques points saillants:
Vous configurez toutes vos vues dans des fichiers .XIB et les enregistrez dans le délégué d'application, tout en initialisant la fabrique.
Maintenant, dans votre VC, chaque fois que vous souhaitez passer à un nouveau VC et transmettre des données, vous créez une nouvelle intention et ajoutez des données à son dictionnaire (savedInstanceState). Ensuite, définissez simplement l'intention actuelle de l'usine:
Toutes vos vues qui se conforment à cela doivent être des sous-classes de MCViewController, qui vous permettent de remplacer la nouvelle méthode onResume:, vous permettant d'accéder aux données que vous avez transmises.
J'espère que certains d'entre vous trouveront cette solution utile / intéressante.
la source
Créez la propriété sur next
view controller .h
et définissez getter et setter.Ajoutez ceci
property
dans NextVC.h sur nextVCAjouter
@synthesize indexNumber;
dans NextVC.mEnfin
la source
Il existe de nombreuses façons de procéder et il est important de choisir la bonne. L'une des plus grandes décisions architecturales repose probablement sur la façon dont le code du modèle sera partagé ou accessible dans l'application.
J'ai écrit un article à ce sujet il y a quelque temps: Partager le code modèle . Voici un bref résumé:
Données partagées
Une approche consiste à partager des pointeurs vers les objets du modèle entre les contrôleurs de vue.
Étant donné que la préparation à la séquence est la plus courante, voici un exemple:
Accès indépendant
Une autre approche consiste à gérer un écran plein de données à la fois et au lieu de coupler les contrôleurs de vue les uns aux autres, coupler chaque contrôleur de vue à une seule source de données à laquelle ils peuvent accéder indépendamment.
La façon la plus courante de voir cela est une instance singleton . Donc, si votre objet singleton était,
DataAccess
vous pouvez effectuer les opérations suivantes dans la méthode viewDidLoad de UIViewController:Il existe des outils supplémentaires qui permettent également de transmettre des données:
Données de base
Ce qui est bien avec Core Data, c'est qu'il a des relations inverses. Donc, si vous voulez simplement donner à NotesViewController l'objet notes, vous pouvez le faire, car il aura une relation inverse avec quelque chose d'autre comme le bloc-notes. Si vous avez besoin de données sur le bloc-notes dans NotesViewController, vous pouvez remonter le graphique d'objet en procédant comme suit:
En savoir plus à ce sujet dans mon article de blog: Partage du code modèle
la source
NewsViewController
NewsDetailViewController.h
NewsDetailViewController.m
la source
La délégation est la seule solution pour effectuer de telles opérations lorsque vous utilisez des fichiers .xib, mais toutes les réponses décrites ci-dessus
storyboard
concernent les fichiers .xibs dont vous avez besoin pour utiliser la délégation. c'est la seule solution que vous pouvez.Une autre solution consiste à utiliser le modèle de classe singleton l'initialiser une fois et à l'utiliser dans l'ensemble de votre application.
la source
si vous souhaitez transmettre des données de ViewControlerOne à ViewControllerTwo, essayez-les.
faites-les dans ViewControlerOne.h
faites-les dans ViewControllerTwo.h
Synthétiser str2 dans ViewControllerTwo.m
faites-les dans ViewControlerOne.m
sur les boutons cliquez sur l'événement, procédez comme suit.
faites-les dans ViewControllerTwo.m
la source
Vous pouvez enregistrer des données dans Délégué d'application pour y accéder via les contrôleurs de vue de votre application. Tout ce que vous avez à faire est de créer une instance partagée de délégué d'application
Par exemple
si vous déclarez un,
NSArray object *arrayXYZ
vous pouvez y accéder dans n'importe quel contrôleur de vue enappDelegate.arrayXYZ
la source
Si vous souhaitez envoyer des données de l'un à l'autre viewController, voici une façon de procéder:
Disons que nous avons viewControllers: ViewController et NewViewController.
dans ViewController.h
dans ViewController.m
Dans NewViewController.h
Dans NewViewController.m
Ainsi, de cette façon, nous pouvons transmettre les données d'un contrôleur de vue à un autre contrôleur de vue ...
la source
J'aime l'idée des objets Model et des objets Mock basés sur NSProxy pour valider ou supprimer les données si ce que l'utilisateur sélectionne peut être annulé.
Il est facile de transmettre des données car il s'agit d'un seul objet ou de deux objets et si vous avez, disons, le contrôleur UINavigationController, vous pouvez conserver la référence au modèle à l'intérieur et tous les contrôleurs de vue poussés peuvent y accéder directement à partir du contrôleur de navigation.
la source
J'ai vu beaucoup de gens compliquer cela en utilisant la
didSelectRowAtPath
méthode. J'utilise Core Data dans mon exemple.4 lignes de code à l'intérieur de la méthode et vous avez terminé.
la source
Il existe de nombreuses réponses à ces questions offrant de nombreuses façons différentes d'effectuer une communication avec le contrôleur de vue qui fonctionnerait effectivement, mais je ne vois nulle part mentionné laquelle est réellement la meilleure à utiliser et laquelle éviter.
En pratique, à mon avis, seules quelques solutions sont recommandées:
prepare(for:sender:)
méthodeUIViewController
lors de l'utilisation d'un storyboard et de séquencesSolutions que je recommande de NE PAS utiliser:
Ces solutions, bien que fonctionnant à court terme, introduisent trop de dépendances qui brouilleront l'architecture de l'application et créeront plus de problèmes plus tard.
Pour ceux qui sont intéressés, j'ai écrit quelques articles qui abordent ces points de manière plus approfondie et mettent en évidence les différents inconvénients:
la source