2

zu übergeben Ich habe eine Sequenz von 4 ViewControllers in einem NavigationController, jeder packt ein paar textFields der Eingabe vom Benutzer, die in einem NSMutableDictionary gespeichert sind.Versuchen, Daten zwischen ViewControllern

Jeder der VCs setzt sich selbst als Delegat des nextVC bevor es segnet, es gibt auch das NSMutDict mit.

Das funktioniert gut.

Was ich nicht verstehe, ist dies:

sagen, dass ich in den 5 Textfelder in VC1 gefüllt haben. Dann setze ich mich als Delegierter von VC2, übergebe VC2 das Wörterbuch mit den Eingabedaten und gehe zu VC2. In VC2 fülle ich noch 4 textFields und füge diese zum Wörterbuch hinzu. Wenn ich dann entscheide, dass ich etwas in VC1 ändern muss, tippe ich auf die Zurück-Schaltfläche und ändere die Daten. Aber wenn ich wieder vorwärts gehe, verliere ich die Sachen, die ich auf VC2 eingegeben habe.

Wie übergebe ich das Wörterbuch zurück an VC1 mit den hinzugefügten Informationen, so dass, wenn es wieder an VC2 weitergeleitet wird, alles drin ist?

Der Delegat (VC1) hat eine Methode, um sein Wörterbuch mit dem Wörterbuch in VC2 zu aktualisieren.

Ich habe auch das backBarButtonItem in VC2 angepasst, indem Sie es in der PrepareForSegue: -Methode in VC1 festlegen.

Ich glaube, ich bin immer in der Nähe, aber ...

Ich kann nur das Ziel Aktionen erhalten, indem zu arbeiten, um eine leftBarButtonItem in VC2 Einstellung und die Verwendung dieser anstelle der Standardschaltfläche zurück.

Das Zurücksetzen der Schaltfläche in VC1 (prepareForSegue :) lässt anscheinend kein Ziel oder keine Aktion zu.

Ich weiß, ich kann nicht die Zurück-Taste in VC2, also was kann ich tun? Kann ich das Ziel und die Aktion der Zurück-Schaltfläche von VC2 mit dem Delegaten festlegen?

Ich denke, es kann etwas mit UINavigationBarDelegate zu tun, aber ich kann nicht herausfinden, wo was damit zu setzen. Ich habe versucht, es in VC2 einzurichten, aber es hat nichts getan.

TIA.

Hier ist der relevante Code:

Protokoll:

#import <Foundation/Foundation.h> 

@protocol IAXAddNewUserDelegate <NSObject> 
@required 
- (void)updateNewUserDataWithData: (NSMutableDictionary *)newData; 

@end 

Von VC1.h:

#import "IAXAddNewUserDelegate.h" 

@interface IAXAddNewUser1 : UITableViewController <UITextFieldDelegate, UIAlertViewDelegate, IAXAddNewUserDelegate> 

@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext; 
@property (strong, nonatomic) User *selectedUser; 
@property (strong, nonatomic) User *aNewUser; 
@property BOOL isFirstUser; 

- (void)updateNewUserDataWithData: (NSMutableDictionary *)newData; 

@end 

Von VC1.m:

#pragma mark - Segues 
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([segue.identifier isEqualToString:@"AddUser2"]) { 
     IAXAddNewUser2 *addUser2VC = segue.destinationViewController; 
     addUser2VC.managedObjectContext = self.managedObjectContext; 
     addUser2VC.progressTotal = self.progressTotal; 
     addUser2VC.isFirstUser = self.isFirstUser; 
     addUser2VC.userData = self.userData; 
     addUser2VC.delegate = self; 
     if (self.selectedUser) { 
      addUser2VC.selectedUser = self.selectedUser; 
     } 
     self.title = @"Step 1"; 
     UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" 
                     style:UIBarButtonItemStyleBordered 
                     target:self 
                     action:@selector(passDataBack:)]; 
     self.navigationItem.backBarButtonItem = backButton; 
    } 
} 

#pragma mark - IAXAddNewUserDelegate Methods 
- (void)updateNewUserDataWithData: (NSMutableDictionary *)newData 
{ 
    self.userData = newData; 
    NSLog(@"Updated AddUserVC1"); 
} 

Von VC2.m

-(void)passDataBack:(id)sender 
{ 
    NSLog(@"Sending Data Back to VC1"); 
    [self.delegate updateNewUserDataWithData:self.userData]; 
    [self.navigationController popViewControllerAnimated:YES]; 
} 
+0

Meine Antwort unten zeigt Ihnen, wie Sie mit deutlich weniger Code machen, was Sie tun möchten, ohne Ihnen zu sagen, wie Sie den "Zurück" -Button umgehen müssen. – AMayes

Antwort

1

Wenn Sie alle Wörterbücher aus allen anderen Wörterbüchern aktualisieren, versuchen Sie es mit einem Singleton. Sie können ein Beispiel hier sehen: https://stackoverflow.com/a/9690731/542400

Auch hier ist ein Code:

MainDictionary.h

@interface MainDictionary : NSObject{ 
    NSMutableDictionary *dictionary; 
} 

+(MainDictionary *)sharedDictionary; 
-(NSString *)getStringForKey:(NSString *)string; 
-(void)setString:(NSString *)string forKey:(NSString *)key; 
@end 

MainDictionary.m

#import "MainDictionary.h" 

static MainDictionary *sharedDictionary; 

@implementation MainDictionary 

-(id)init{ 
    self = [super init]; 
    dictionary = [[NSMutableDictionary alloc] init]; 
    // if you want to add anything preliminary to the dictionary, do it here 
    return self; 
} 

+(MainDictionary *)sharedDictionary{ 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
    sharedDictionary = [[self alloc] init]; 
    }); 
return sharedDictionary; 
} 
-(NSString *)getStringForKey:(NSString *)string{ 
    return [dictionary objectForKey:string]; 
} 
-(void)setString:(NSString *)string forKey:(NSString *)key{ 
    [dictionary setValue:string forKey:key]; 
} 
@end 

Jetzt #import MainDictionary.h und jedes Mal, wenn Sie zugreifen möchten, oder setzen Werte in diesem Wörterbuch (in diesem Beispiel, wenn Ihre Textfelder Ende Bearbeitung), gerade dies zu tun:

-(void)textFieldDidEndEditing:(UITextField *)textField{ 
    if(textField == textField1){ 
     [[MainDictionary sharedDictionary] setString: textField.text forKey:@"textField1"]; 
    } 
} 

oder:

-(void)viewWillAppear{ 
    textField1.text = [[MainDictionary sharedDictionary] getStringForKey:@"textField1"]; 
    [super viewWillAppear:YES]; 
} 

Implementieren Sie dies in jedem VC, und Sie sind gut zu gehen.

+0

Danke für den Vorschlag. Ich habe über diesen Ansatz nachgedacht, würde es aber lieber so machen, wie ich es für richtig halte. Abgesehen davon, dass es mich WIRKLICH nervt, dass ich es nicht zur Arbeit bringen kann, es fühlt sich einfach so an, als müsste es so einfach sein! – Bertie

+0

Ja, ich hatte genau dieses Problem vor einiger Zeit und implementierte eine sehr komplexe Problemumgehung. Diese Lösung ist weit überlegen, da sie modular ist, und Sie können die Singletons in neuen Ansichten und neuen Projekten mit sehr wenig Codierung verwenden. – AMayes