2

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

我想简单地从 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
4

4 回答 4

3

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

对于基于故事板的项目,这通常在prepareForSegue:. 在执行第二个视图控制器的 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;
        }
    }
    

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

于 2012-08-04T09:38:07.220 回答
1

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

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

ViewController *myVC1; 
ViewController2 *myVC2;

// ...some initialization.

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

一切都会奏效。

于 2012-08-04T00:34:27.613 回答
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;
}
于 2012-08-04T00:23:46.863 回答
0

尝试使用 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];
}

希望这可以帮助!

于 2012-08-04T01:05:23.647 回答