如何将NSString从一个View Controller传递到另一个?

时间:2012-08-04 00:16:18

标签: objective-c properties uiviewcontroller nsstring scope

我用两个View Controller制作了一个非常简单的基于故事板的项目。

我想简单地从VC2访问VC1中声明的字符串。然后,第二个VC应该在按下按钮时在文本字段中显示文本。

我不想使用委托单独的全局数据类全局变量和Extern 。相反,我读到在另一个VC中使用对一个VC的引用很容易实现变量共享。

对于我下面显示的代码,XCode没有抱怨,但我的问题是:第二个VC中的NSLog返回null。

如果有人可以告诉我如何修改代码以将字符串传递给第二个VC /告诉我哪里出错了我会很感激。

VC1标题:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property NSString* textToPassToOtherVC;

VC1实施:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize textToPassToOtherVC = _textToPassToOtherVC;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    _textToPassToOtherVC = @"Here is some text";
    NSLog (@"Text in VC1 is: %@", _textToPassToOtherVC);
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end

VC2标题:

#import <UIKit/UIKit.h>

@class ViewController;

@interface ViewController2 : UIViewController

@property (nonatomic, strong) ViewController *received;

@property (strong, nonatomic) IBOutlet UITextField *textDisplay;

- (IBAction)textButton:(id)sender;

@end

VC2实施:

#import "ViewController2.h"
#import "ViewController.h"

@interface ViewController2 ()

@end

@implementation ViewController2
@synthesize textDisplay;
@synthesize received;

- (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.

}

- (void)viewDidUnload
{
    [self setTextDisplay:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

- (IBAction)textButton:(id)sender {

    NSLog (@"Text in VC1 from VC2 is: %@", self.received.textToPassToOtherVC);

    textDisplay.text = self.received.textToPassToOtherVC;
}
@end

4 个答案:

答案 0 :(得分:3)

您的第二个视图控制器需要将其received属性设置为表示第一个视图控制器的值。

通过基于故事板的项目,这通常在prepareForSegue:中完成。在执行到第二个视图控制器的segue之前,将在第一个视图控制器中调用此方法。

(在我看来,最好只将字符串传递给第二个视图控制器而不是指向整个视图控制器的指针,因为这会减少依赖性,并且是第二个视图控制器真正需要的唯一信息,但是让我们不要复杂化。)

以下是我认为您需要采取的步骤:

  • 将第一个视图控制器中的segue提供给故事板中的第二个名称。对于此示例,我将其称为mySegue
  • 在“ViewController.m”中导入“ViewController2.h” - 您的第一个视图控制器需要知道第二个视图控制器具有received属性。
  • 在第一个视图控制器中添加prepareForSegue:方法,如下所示:

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([segue.identifier isEqualToString:@"mySegue"])
        {
            ViewController2 *targetVC = (ViewController2*)segue.destinationViewController;
            targetVC.received = self;
        }
    }
    

希望很清楚这段代码在做什么。

答案 1 :(得分:1)

你的错误是基于对财产的根本误解。属性只是用于处理样板和getter和setter的实现细节的语法糖。虽然设置_textToPassToOtherVC确实会使属性返回该值,但它不会“通知”另一个,因为它对“received”的引用默认设置为nil,并且永远不会由你设置。

如果您在实际检查此共享文本的值之前的任何地方,您可以使用以下行:

ViewController *myVC1; 
ViewController2 *myVC2;

// ...some initialization.

myVC2.received = myVC1;
// Now the IBAction will display the correct text.

一切都会奏效。

答案 2 :(得分:0)

您是否检查过self.received不是null / nil?

在代码中设置一个断点,看看self.received是否实际初始化(如果不是,那就是你没有看到任何东西的原因):

- (IBAction)textButton:(id)sender {

    // Breakpoint here
    NSLog (@"Text in VC1 from VC2 is: %@", self.received.textToPassToOtherVC);

    textDisplay.text = self.received.textToPassToOtherVC;
}

答案 3 :(得分:0)

尝试使用NSNotification。当您需要发送字符串时,使用对象发布NSNotification!

当您想要发送字符串时(在给字符串赋值后):

    yourString = @"Hello";

    [[NSNotificationCenter defaultCenter] postNotificationName:@"sendString" object:yourString];

并在您的第二个View Controller中:

-(void)viewDidLoad:
{
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ThingYouWantToDoWithString:) name:@"sendString" object:nil];
}

- (void)ThingYouWantToDoWithString:(NSNotification *)notification{
        // Make sure you have an string set up in your header file or just do NSString *theString = [notification object] if your using ARC, if not allocate and initialize it and then do what I just said
        theString = [notification object];
        NSLog("%@", theString);
        [self performSelector:@selector(OtherThings:) object:theString];
}

希望这有帮助!