1. ホーム
  2. iphone

[解決済み] dismissModalViewControllerとデータの受け渡し

2023-07-21 10:14:12

質問

2つのビューコントローラがあります。 firstViewController secondViewController . 私はこのコードを使ってsecondViewControllerに切り替えています(文字列も渡しています)。

secondViewController *second = [[secondViewController alloc] initWithNibName:nil bundle:nil];

second.myString = @"This text is passed from firstViewController!";

second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

[self presentModalViewController:second animated:YES];

[second release];

そして、secondViewControllerでこのコードを使って、firstViewControllerに切り替えています。

[self dismissModalViewControllerAnimated:YES];

これらはすべて問題なく動作します。質問ですが、firstViewControllerにどのようにデータを渡せばいいのでしょうか?secondViewControllerからfirstViewControllerに違う文字列を渡したいのですが。

どのように解決するのでしょうか?

デリゲートプロトコルを使用する必要があります... その方法を説明します。

secondViewControllerのヘッダーファイルでプロトコルを宣言してください。以下のような感じです。

#import <UIKit/UIKit.h>

@protocol SecondDelegate <NSObject>
-(void)secondViewControllerDismissed:(NSString *)stringForFirst
@end


@interface SecondViewController : UIViewController
{
    id myDelegate;  
}

@property (nonatomic, assign) id<SecondDelegate>    myDelegate;

実装(SecondViewController.m)ファイル内でmyDelegateを合成することを忘れないでください。

@synthesize myDelegate;

FirstViewControllerのヘッダーファイルで、以下のようにしてSecondDelegateプロトコルをサブスクライブしてください。

#import "SecondViewController.h"

@interface FirstViewController:UIViewController <SecondDelegate>

さて、FirstViewControllerの中にSecondViewControllerをインスタンス化するときは、以下のようにする必要があります。

// If you're using a view controller built with Interface Builder.
SecondViewController *second = [[SecondViewController alloc] initWithNibName:"SecondViewController" bundle:[NSBundle mainBundle]];
// If you're using a view controller built programmatically.
SecondViewController *second = [SecondViewController new]; // Convenience initializer that uses alloc] init]
second.myString = @"This text is passed from firstViewController!";
second.myDelegate = self;
second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:second animated:YES];
[second release];

最後に、最初のビューコントローラの実装ファイル(FirstViewController.m)において、SecondDelegateのsecondViewControllerDismissedのメソッドを実装してください。

- (void)secondViewControllerDismissed:(NSString *)stringForFirst
{
    NSString *thisIsTheDesiredString = stringForFirst; //And there you have it.....
}

さて、2つ目のビューコントローラを終了させようとするとき、1つ目のビューコントローラに実装されているメソッドを呼び出したいと思います。この部分は簡単です。2 番目のビューコントローラの dismiss のコードの前に、いくつかのコードを追加するだけです。

if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:)])
{
    [self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!"];
}
[self dismissModalViewControllerAnimated:YES];

デリゲートプロトコルは非常に、非常に、非常に便利です。それらに精通することは良いことです :)

NSNotificationsはこれを行う別の方法ですが、ベストプラクティスとして、私は複数のviewControllerまたはオブジェクトにわたって通信したいときにこれを使用することを好みます。NSNotificationsの使用について興味がある方は、以前投稿した回答をご覧ください。 appdelegateのスレッドから複数のビューコントローラーにまたがるイベントを発生させる

EDITです。

複数の引数を渡したい場合、dissue前のコードはこのようになります。

if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:argument2:argument3:)])
{
    [self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!" argument2:someObject argument3:anotherObject];
}
[self dismissModalViewControllerAnimated:YES];

つまり、firstViewControllerの中のSecondDelegateメソッドの実装は以下のようになります。

- (void) secondViewControllerDismissed:(NSString*)stringForFirst argument2:(NSObject*)inObject1 argument3:(NSObject*)inObject2
{
    NSString thisIsTheDesiredString = stringForFirst;
    NSObject desiredObject1 = inObject1;
    //....and so on
}