我如何将NSString从一个视图控制器传递到另一个



我用两个视图控制器做了一个非常简单的基于故事板的项目。

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

我不想使用委派,一个用于全局数据的独立类全局变量和Extern。相反,我读到使用对另一个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

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

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

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

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

  • 在故事板中为从第一个视图控制器到第二个视图控制器的片段命名。对于这个例子,我将称之为mySegue
  • 在"ViewController.m"中导入"ViewController 2.h"-第一个视图控制器需要知道第二个视图控制器具有received属性
  • 在您的第一个视图控制器中添加类似的prepareForSegue:方法:

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

希望这段代码的作用非常清楚。

您的错误是基于对属性的根本误解。属性只是处理getter和setter的样板和实现细节的语法糖。尽管设置_textToPassToOtherVC确实会使属性返回该值,但它不会"通知"其他属性,因为默认情况下,它对"received"的引用设置为nil,而您从未设置过。

如果在您实际检查此共享文本的值之前,您有以下行:

ViewController *myVC1; 
ViewController2 *myVC2;
// ...some initialization.
myVC2.received = myVC1;
// Now the IBAction will display the correct text.

一切都会好起来的。

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

当你想发送字符串时(当然是在你给字符串一个值之后):

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

在您的第二个视图控制器中:

-(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];
}

希望这能有所帮助!

您是否检查过您的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;
}

最新更新