2

2つのViewControllerを使用して非常に単純なストーリーボードベースのプロジェクトを作成しました。

VC2からVC1で宣言された文字列にアクセスしたいだけです。2番目のVCは、ボタンを押すとテキストフィールドにテキストを表示する必要があります。

グローバルデータまたはグローバル変数とExternの個別のクラスである委任を使用したくありません。代わりに、一方のVCをもう一方のVCに参照することで、変数の共有を簡単に実現できることを読みました。

以下に示す私のコードでは、XCodeは文句を言いませんでしたが、私の問題は次のとおりです。2番目のVCのNSLogがnullを返します。

誰かがコードを修正して文字列を2番目の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

2 番目のビュー コントローラーのreceivedプロパティは、最初のビュー コントローラーを表す値に設定する必要があります。

絵コンテベースのプロジェクトでは、これは通常 で行われprepareForSegue:ます。このメソッドは、2 番目のビュー コントローラーへのセグエが実行される前に、最初のビュー コントローラーで呼び出されます。

(私の意見では、依存関係を減らし、2番目のView Controllerが本当に必要とする唯一の情報であるため、View Controller全体へのポインターではなく、2番目のView Controllerに文字列だけを渡す方が良いでしょうが、複雑にしないでください。)

これを機能させるために必要だと思う手順は次のとおりです。

  • ストーリーボードで、最初のビュー コントローラーから 2 番目のビュー コントローラーへのセグエに名前を付けます。この例では、 と呼びますmySegue
  • "ViewController.m" に "ViewController2.h" をインポートします。最初のビュー コントローラーは、2 番目のビュー コントローラーにプロパティがあることを認識する必要があり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

あなたの間違いは、プロパティの根本的な誤解に基づいています。プロパティは、ゲッターとセッターのボイラープレートと実装の詳細を処理するための単なる構文糖衣です。_textToPassToOtherVC を設定すると、実際にプロパティがその値を返すようになりますが、「受信済み」への参照はデフォルトで 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.receivednull/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];

そしてあなたの2番目の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];
}

お役に立てれば!

于 2012-08-04T01:05:23.647 に答える