简体   繁体   English

iOS使用presentModalSegue将数据从viewController2传递回viewController 1

[英]iOS Pass data back from viewController2 to viewController 1 with presentModalSegue

I have viewController1 that makes a modal segue to my viewController2 but the 我有viewController1对我的viewController2进行模态选择,但是

viewController2 is embebed on a navigation controller viewController2嵌入在导航控制器上

because I need the navigation bar there. 因为我在那里需要导航栏。

I've implemented a protocol to send the data back from viewController2 to viewController1 but it doesn't function. 我已经实现了一个协议,用于将数据从viewController2发送回viewController1,但是它不起作用。 Here is my code: 这是我的代码:

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
            }
        }

    }
}

On the viewController2 I have this: 在viewController2上我有:

class viewController2: UIViewController{
    var delegate: writeValueBackDelegate?

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

I dont know why but it functions only if I remove the navigation controller from my secondviewController and make the segue from viewController 1 to viewController 2 directly, but I need the navigation controller to show the navigation bar. 我不知道为什么,但是只有当我从secondviewController中移除导航控制器并直接将其从viewController 1切换到viewController 2时,它才起作用,但是我需要导航控制器来显示导航栏。

Do you know why it is happening? 你知道为什么会这样吗? or Why I'm doing bad. 还是为什么我做得不好。

Here is my understanding of your setup. 这是我对您的设置的理解。

ViewController1 -> NavigationController -> ViewController2 ViewController1-> NavigationController-> ViewController2

In this case, in the prepare for segue method, the destination viewcontroller is the Navigation Controller and Not ViewController2. 在这种情况下,在“准备segue”方法中,目标视图控制器是“导航控制器”而不是“ ViewController2”。 Therefore, this line of code will not be true. 因此,这行代码将不正确。

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

The downcast you have there will fail, because the destination VC is not MapAddressViewContoller,instead its a UINavigation controller. 您在那里进行的向下转换将失败,因为目标VC不是MapAddressViewContoller,而是其UINavigation控制器。

To fix this, you can change the code as follows : 要解决此问题,您可以更改代码,如下所示:

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

However, I prefer using NSNotification to pass data back down the view controller hierarchy. 但是,我更喜欢使用NSNotification将数据传回视图控制器层次结构。 You could try that out also. 您也可以尝试一下。

Using Notifications : 使用通知:

  • Step 1 : In VC1 : Register for a notification. 步骤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!)") }
    • Step 2 : In VC2 : Post a Notification at an appropriate time. 步骤2:在VC2中:在适当的时间发布通知。 NSNotificationCenter.defaultCenter().postNotificationName("SomeName", object: nil, userInfo: ["theKey":"theData"])

Here is the way doing this through NSNotification and CustomDelegate 这是通过NSNotification和CustomDelegate进行此操作的方法

Let's see the Passing Data from ViewController2 to ViewController1 Using NSNotification first. 让我们首先使用NSNotification查看将数据从ViewController2传递到ViewController1的过程。

in ViewControllerB 在ViewControllerB中

.h 。H

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

.m .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.
}

in ViewControllerA 在ViewControllerA中

.h 。H

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

.m .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.
 }

First we navigate the view from ViewControllerA to ViewControllerB. 首先,我们将视图从ViewControllerA导航到ViewControllerB。

After that we send the data from ViewControllerB to ViewControllerA. 之后,我们将数据从ViewControllerB发送到ViewControllerA。

In above coding we use the NSNotification. 在上面的编码中,我们使用NSNotification。

So that, you need to set the postNotificationName for getting data in button action method in ViewControllerB. 因此,您需要设置postNotificationName以在ViewControllerB中的按钮操作方法中获取数据。

Next you need to write addObserver in (sending data to your required View Controller) ViewControllerA and call the addObserver method in same View Controller. 接下来,您需要在ViewControllerA中写入addObserver (将数据发送到所需的View Controller),并在同一View Controller中调用addObserver方法。

Let's see the Passing Data from ViewController2 to ViewController1 Using CustomDelegate. 让我们看看使用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 .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.
}

in ViewController 在ViewController中

.h 。H

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

.m .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.
 }

In above coding we use the CustomProtocolDelegate Method. 在上面的编码中,我们使用CustomProtocolDelegate方法。

First we need to Set and Assign the delegate in ViewControllerB.h 首先,我们需要在ViewControllerB.h中设置分配委托

Very importantly we have to set the Custom Delegate Method in the ViewControllerB because where we send the data to ViewControllerA once we click the action button in ViewControllerB. 非常重要的是,我们必须在ViewControllerB中设置“ 自定义委托方法” ,因为一旦单击ViewControllerB中的操作按钮,便会将数据发送到ViewControllerA。

Finally we must call the Custom Delegate Method in View ControllerA , where we get the data and assign that data to label.Now you can see the passed data(From ViewControllerB to ViewControllerA) using custom delegate. 最后,我们必须在View ControllerA中调用Custom Delegate方法 ,从中获取数据并将其分配给label。现在,您可以使用自定义委托查看传递的数据(从ViewControllerB到ViewControllerA)。

Likewise you can send the data to other view controller using Custom Delegate Methods or NSNotificationCenter 同样,您可以使用“ 自定义委托方法”或“ NSNotificationCenter”将数据发送到其他视图控制器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用从ViewController2传回的数据更新ViewController1数据 - How do I update ViewController1 data with data passed back from ViewController2 将数据从ViewController传递回根ViewController? - Pass data from ViewController back to root ViewController? 将数据从tableview传递回Viewcontroller - Pass data back to Viewcontroller from tableview 如何在标签栏iOS中将数据从ViewController传递到ViewController? - How to pass data from ViewController to a ViewController in a tab bar iOS? iOS Swift:将数据从ViewController传递到UITableViewCell - iOS Swift: Pass data from ViewController to UITableViewCell Swift:关闭 ViewController2 后从 ViewController1 调用方法 - Swift: Call a method from ViewController1 after dismissing ViewController2 ios将数据从TabbarController传递到Storyboard中的ViewController - ios Pass data from TabbarController to ViewController in Storyboard 将数据传回上一个视图控制器 - Pass data back to previous viewcontroller 将数据从最后一个 ViewController 传递到根 ViewController - Pass Data from last ViewController to root ViewController 将数据从Tableview传递回ViewController文本字段Objective-C - Pass data back from tableview to viewcontroller textfield Objective - C
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM