この回答は、3つの最も重要なアプローチを説明するために書き直され/拡張されました(@galambalazs)
1. ブロック
最も簡単な方法は、 callback を使用することblock
です。これは、却下に関心のあるリスナー(親ビュー コントローラー)が 1 つしかない場合に適しています。イベントでデータを渡すこともできます。
MainViewController.m内
SecondViewController* svc = [[SecondViewController alloc] init];
svc.didDismiss = ^(NSString *data) {
// this method gets called in MainVC when your SecondVC is dismissed
NSLog(@"Dismissed SecondViewController");
};
[self presentViewController:svc animated:YES completion:nil];
SecondViewController.h内
@interface MainViewController : UIViewController
@property (nonatomic, copy) void (^didDismiss)(NSString *data);
// ... other properties
@end
SecondViewController.m内
- (IBAction)close:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
if (self.didDismiss)
self.didDismiss(@"some extra data");
}
2.委任
Delegation
Apple が推奨するパターンは次のとおりです。
提示されたView Controllerを閉じる
提示されたビュー コントローラーが提示元のビュー コントローラーにデータを返す必要がある場合は、委任デザイン パターンを使用して転送を容易にします。委任により、アプリのさまざまな部分でビュー コントローラーを簡単に再利用できます。委任により、提示されたビュー コントローラーは、正式なプロトコルからメソッドを実装するデリゲート オブジェクトへの参照を格納します。結果を収集すると、提示されたビュー コントローラーはデリゲートでこれらのメソッドを呼び出します。典型的な実装では、表示側のビュー コントローラーは、自身を表示されたビュー コントローラーのデリゲートにします。
MainViewController
MainViewController.h内
@interface MainViewController : UIViewController <SecondViewControllerDelegate>
- (void)didDismissViewController:(UIViewController*)vc;
// ... properties
@end
MainViewController.mのどこか(提示)
SecondViewController* svc = [[SecondViewController alloc] init];
svc.delegate = self;
[self presentViewController:svc animated:YES completion:nil];
MainViewController.m の別の場所 (解雇について通知されます)
- (void)didDismissViewController:(UIViewController*)vc
{
// this method gets called in MainVC when your SecondVC is dismissed
NSLog(@"Dismissed SecondViewController");
}
SecondViewController
SecondViewController.h内
@protocol SecondViewControllerDelegate <NSObject>
- (void)didDismissViewController:(UIViewController*)vc;
@end
@interface SecondViewController : UIViewController
@property (nonatomic, weak) id<SecondViewControllerDelegate> delegate;
// ... other properties
@end
SecondViewController.mのどこかに
[self.delegate myActionFromViewController:self];
[self dismissViewControllerAnimated:YES completion:nil];
(注: didDismissViewController: メソッドを使用したプロトコルは、アプリ全体で再利用できます)
3. 通知
別の解決策は、NSNotification
. これも有効なアプローチです。多くのデータを渡さずに解雇について通知するだけの場合は、委任よりも簡単かもしれません。ただし、主な使用例は、解雇イベントに複数のリスナーが必要な場合です(親のビューコントローラーだけではありません)。
ただし、終了後は必ずNSNotificationCentreから自分自身を削除してください。そうしないと、割り当てが解除された後でも通知が呼び出されてクラッシュする危険があります。 【編集者注】
MainViewController.m内
- (IBAction)showSecondViewController:(id)sender
{
SecondViewController *secondVC = [[SecondViewController alloc] init];
[self presentViewController:secondVC animated:YES completion:nil];
// Set self to listen for the message "SecondViewControllerDismissed"
// and run a method when this message is detected
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(didDismissSecondViewController)
name:@"SecondViewControllerDismissed"
object:nil];
}
- (void)dealloc
{
// simply unsubscribe from *all* notifications upon being deallocated
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)didDismissSecondViewController
{
// this method gets called in MainVC when your SecondVC is dismissed
NSLog(@"Dismissed SecondViewController");
}
SecondViewController.m内
- (IBAction)close:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
// This sends a message through the NSNotificationCenter
// to any listeners for "SecondViewControllerDismissed"
[[NSNotificationCenter defaultCenter]
postNotificationName:@"SecondViewControllerDismissed"
object:nil userInfo:nil];
}
お役に立てれば!