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"])
- 步骤2:在VC2:在适当的时间发布通知。
这是通过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将数据发送到其他视图控制器
- 如何animation一个Sprite-Kit游戏的背景,就像Instagram的iOS应用程序的login屏幕?
- 如何在UIScrollview中embedded一个UITableView
- 我应该使用什么,而不是在iOS5.1中弃用的UISegmentedControlStyleBezeled?
- Maple Lawn Guide登陆由Revista支持的iOS App Store
- 如何调整OpenEars错误识别
- 应用必须遵循iOS数据存储准则,否则将在包含.sqlite3的应用中被拒绝
- iPhone内存泄漏
- Xcode中的iOS 9警告 – 此文件设置为构build比项目部署早的版本。 function可能受到限制
- 如何删除Swift iOS8中的最后一张照片?