2

ストーリーボードに切り替えてから、ビューコントローラーを次の方法でロードします

[self performSegueWithIdentifier:@"identifier" sender:self]

これは完全に機能します。ここで、宛先ビュー コントローラーにプロパティを設定する場合は、メソッドを実装し、prepareForSegue:sender:設定する必要があるプロパティを設定します。すべてが問題なく期待どおりに機能します。

古いものよりもこのアプローチを使い始めて以来

MyViewController *vc = ....
vc.prop = @"value";
[self.navigationController pushViewController:vc];

特に、設定しようとしている値が単なる静的な値ではない場合、パラメーターを宛先ビューコントローラーに渡すのは少しハックだと感じました。

たとえば、サーバーからデータを取得するボタンがあるとします。データが返されると、新しいオブジェクトが作成され、このオブジェクトを表示する新しいビュー コントローラーが提示されます。これを行うために を呼び出しますperformSegueWithIdentifier:sender:が、それで終わりです。オブジェクトの割り当てが解除され、存在しなくなりprepareForSegue:sender:ました。インスタンス変数に格納しない限り、オブジェクトをメソッドに渡す方法がありません。

オブジェクトはこのアクションよりも長く続くことを意図しておらず、現在のビュー コントローラーの他のものとは何の関係もないため、これはかなり恐ろしいことです。

この状況では、新しいView Controllerでデータを簡単にリクエストできることは理解していますが、これは単なる例です。

私の質問は、それほどハッキーに感じずにこれを行う別の方法はありますか? このデータをインスタンス変数に格納せずに、宛先のビュー コントローラーに入れることはできますか?

古いアプローチを引き続き使用できることはわかっていますが、できればストーリーボードの方法を使い続けたいと思います。

4

3 に答える 3

4

senderパラメータは、performSegueWithIdentifier:senderが受け取ったものと同じprepareForSegue:senderです。prepareForSegue:senderしたがって、変数を自分に送信したい場合senderは、友達です。あなたの場合:

SomeViewController.m

-(void)aMethodThatDownloadsSomeDataFromServer {
   NSString *exampleData = [self someDataThatIDownloaded];
   [self performSegueWithIdentifier:@"yourSegueIdentifier" sender:exampleData];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
   if(segue.identifier isEqualToString:@"yourSegueIdentifier"]) { 
      if([sender isKindOfClass:[NSString class]]) { //maybe you want to send different objects
        segue.destinationViewController.stringProperty = sender;
      }
      else { 
        segue.destinationViewController.objectPorperty = sender;
      }
   }
}
于 2013-08-19T12:08:57.163 に答える
0

これらの答えはすべて正しいですが、これを行うためのかなりクールな方法を見つけました。iOS 7 と iOS 8 でのみテストしました

渡したいオブジェクトの値を宣言・設定した後、prepareForSegueメソッドで、

    [segue.destinationViewController setValue:event forKey:@"property"];
//write your property name instead of "property
于 2014-06-10T22:43:17.003 に答える
0

受け入れられた解決策は正しいですが、データが 2 つ以上のセグエ間で共有されている場合は、別のアプローチを頻繁に使用します。私は頻繁にシングルトン クラス (APPSession と呼びましょう) を作成し、それをデータモデルとして使用して、コードのどこからでも読み書きできるセッションのような構造を作成および維持します。

複雑なアプリケーションの場合、このソリューションにはエラーが発生しやすいコーディングが必要になる可能性がありますが、私はさまざまな場面でうまく使用してきました。

APPSession.m

//
//  APPSession.m
//
//  Created by Luca Adamo on 09/07/12.
//  Copyright 2012 ELbuild. All rights reserved.
//

#import "APPSession.h"

@implementation APPSession
@synthesize myProperty;

static APPSession *instance = nil;

// Get the shared instance and create it if necessary.
+ (APPSession *)instance {
    if (instance == nil) {
        instance = [[super allocWithZone:NULL] init];
    }

    return instance;
}

// Private init, it will be called once the first time the singleton is created
- (id)init
{
    self = [super init];

    if (self) {
        // Standard init code goes here
    }

    return self;
}

// This will never be called since the singleton will survive until the app is finished. We keep it for coherence.
-(void)dealloc
{

}

// Avoid new allocations
+ (id)allocWithZone:(NSZone*)zone {
    return [self sharedInstance];
}

// Avoid to create multiple copies of the singleton.
- (id)copyWithZone:(NSZone *)zone {
    return self;
}

APPSession.h

//
//  APPSession.h
//
//  Created by Luca Adamo on 09/07/12.
//  Copyright 2012 ELbuild. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface APPSession : NSObject{

}

@property(nonatomic,retain) NSString* myProperty;

+ (id)sharedInstance;

@end

アプリ コードのあらゆる部分からプロパティmyPropertyを読み書きする方法。

// How to write "MyValue" to myProperty NSString * 
[APPSession instance] setMyProperty:@"myValue"]
// How to read myProperty
NSString * myVCNewProperty = [[APPSession instance] myProperty];

このメカニズムを使用すると、たとえば、最初の ViewController の APPSession に値を安全に書き込み、2 番目の ViewController へのセグエを実行し、3 番目のセグエへの別のセグエを実行し、最初のセグエで書き込まれた変数を使用できます。

これは多かれ少なかれ Java EE の SessionScoped JavaBean に似ています。このアプローチの問題点を遠慮なく指摘してください。

于 2013-09-14T19:34:33.850 に答える