iOS将数据从viewController2传递回给presentModalSegue的viewController 1

我有viewController1,使模式segue我的viewController2,但

viewController2embedded在导航控制器上

因为我需要那里的导航栏。

我已经实现了一个协议,从viewController2发回的数据viewController1,但它不起作用。 这是我的代码:

protocol writeValueBackDelegate { func writeValueBack(value: String) } class viewController1: UITableViewController, writeValueBackDelegate { override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "SelectAddress"{ if let dest = segue.destinationViewController as? MapAddressViewController{ dest.delegate = self } } } } 

在viewController2我有这个:

 class viewController2: UIViewController{ var delegate: writeValueBackDelegate? @IBAction func TaskOneClick(sender: AnyObject) { delegate?.writeValueBack(txtAddress!.text!) self.navigationController?.popViewControllerAnimated(true) } } 

我不知道为什么,但它的function只有当我从我的secondviewController删除导航控制器,并从viewController 1直接viewController 2 segue,但我需要导航控制器来显示导航栏。

你知道这是为什么吗? 或为什么我做得不好。

这是我对你的设置的理解。

ViewController1 – > NavigationController – > ViewController2

在这种情况下,在准备segue方法时,目标视图控制器是导航控制器而不是ViewController2。 因此,这行代码不会是真的。

 if let dest = segue.destinationViewController as? MapAddressViewController{ dest.delegate = self } 

你在那里的沮丧将会失败,因为目标VC不是MapAddressViewContoller,而是它的一个UINavigation控制器。

要解决这个问题,你可以改变代码如下:

 if let dest = segue.destinationViewController as? UINavigationController{ dest.rootViewController.delegate = self } 

不过,我更喜欢使用NSNotification将数据传递回视图控制器层次结构。 你也可以尝试一下。

使用通知:

  • 步骤1:在VC1:注册通知。 override func viewDidLoad() { NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("myFunc:"), name: "SomeName", object: nil) } func myFunc(theNotifiction : NSNotification){ print("I got notified (theNotifiction.userInfo!)") }
    • 步骤2:在VC2:在适当的时间发布通知。 NSNotificationCenter.defaultCenter().postNotificationName("SomeName", object: nil, userInfo: ["theKey":"theData"])

这是通过NSNotification和CustomDelegate做到这一点

让我们看看从ViewController2传递给ViewController1的数据首先使用NSNotification。

在ViewControllerB中

。H

 #import <UIKit/UIKit.h> @interface ViewControllerB : UIViewController @property (nonatomic, strong) IBOutlet UITextField *txtAddress; - (IBAction)TaskOneClick:(id)sender; @end 

.M

 #import "ViewControllerB.h" @interface ViewControllerB () @end @implementation ViewControllerB - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. } //Using NSNotification - (IBAction)TaskOneClick:(id)sender; { //Use NSNotificationCenter [[NSNotificationCenter defaultCenter] postNotificationName:@"passingDataFromSecondViewToFirstView" object:self.txtAddress.text]; [self.navigationController popViewControllerAnimated:YES]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } 

在ViewControllerA中

。H

 #import <UIKit/UIKit.h> #import "ViewControllerB.h" @interface ViewControllerA : UIViewController<ViewControllerBDelegate> @property (nonatomic, strong) IBOutlet UILabel *labelGetData; - (IBAction)gotoNextView:(id)sender; @end 

.M

 #import "ViewControllerA.h" @interface ViewControllerA () @end @implementation ViewControllerA - (void)viewDidLoad { [super viewDidLoad]; //addObserver here... [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFromPreviousViewControllerNotificationReceived:) name:@"passingDataFromSecondViewToFirstView" object:nil]; // Do any additional setup after loading the view, typically from a nib. } //addObserver Method here.... - (void)textFromPreviousViewControllerNotificationReceived:(NSNotification *)notification { // set text to label... NSString *string = [notification object]; self.labelGetData.text = string; } - (IBAction)gotoNextView:(id)sender; { //If you use storyboard ViewControllerB *viewControllerB = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewControllerB"]; //OR If you use XIB ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNibName:@"ViewControllerB" bundle:nil]; [self.navigationController pushViewController:viewControllerB animated:YES]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } 

首先我们将ViewControllerA中的视图导航到ViewControllerB。

之后,我们将数据从ViewControllerB发送到ViewControllerA。

在上面的编码中,我们使用NSNotification。

所以,你需要设置postNotificationName来获取ViewControllerB中button操作方法中的数据。

接下来,您需要编写addObserver (将数据发送到您需要的View Controller)ViewControllerA,并在同一个View Controller中调用addObserver方法。

让我们看看使用CustomDelegate从ViewController2传递给ViewController1的数据。

  in ViewControllerB .h #import <UIKit/UIKit.h> @class ViewControllerB; @protocol ViewControllerBDelegate <NSObject> - (void)viewControllerB:(ViewControllerB *)viewControllerB didEnterText:(NSString *)text; @end @interface ViewControllerB : UIViewController @property (nonatomic, assign)id<ViewControllerBDelegate> delegate; @property (nonatomic, strong) IBOutlet UITextField *txtAddress; - (IBAction)TaskOneClick:(id)sender; @end 

.M

 #import "ViewControllerB.h" @interface ViewControllerB () @end @implementation ViewControllerB - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. } //Using Custom Delegate - (IBAction)TaskOneClick:(id)sender; { [self.delegate viewControllerB:self didEnterText:self.txtAddress.text]; [self.navigationController popViewControllerAnimated:YES]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } 

在ViewController中

。H

 #import <UIKit/UIKit.h> #import "ViewControllerB.h" @interface ViewControllerA : UIViewController<ViewControllerBDelegate> @property (nonatomic, strong) IBOutlet UILabel *labelGetData; - (IBAction)gotoNextView:(id)sender; @end 

.M

 #import "ViewControllerA.h" @interface ViewControllerA () @end @implementation ViewControllerA - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (IBAction)gotoNextView:(id)sender; { //If you use storyboard ViewControllerB *viewControllerB = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewControllerB"]; //OR If you use XIB ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNibName:@"ViewControllerB" bundle:nil]; viewControllerB.delegate = self; [self.navigationController pushViewController:viewControllerB animated:YES]; } //Calling custom delegate method - (void)viewControllerB:(ViewControllerB *)ViewControllerB didEnterText:(NSString *)text { self.labelGetData.text = text; //Getting the data and assign the data to label here. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } 

在上面的编码中,我们使用CustomProtocolDelegate方法。

首先我们需要在ViewControllerB.h中设置分配委托

非常重要的是,我们必须在ViewControllerB中设置自定义委托方法 ,因为一旦我们点击ViewControllerB中的操作button,我们将数据发送到ViewControllerA。

最后,我们必须在View ControllerA中调用自定义委托方法 ,在那里我们获取数据并将数据分配给标签。现在,您可以使用自定义委托来查看传递的数据(从ViewControllerB到ViewControllerA)。

同样,您可以使用自定义委托方法或NSNotificationCenter将数据发送到其他视图控制器