64

重複の可能性:
モーダルビューコントローラーが閉じられているため、基になるViewControllerの関数を呼び出す

私はほとんどすべてを試しました。これが私が試したことです:

-(void)viewWillAppear:(BOOL)animated
{

NSLog(@"Test");

}

-(void)viewDidAppear:(BOOL)animated
{

NSLog(@"Test");

}

-(void)viewDidLoad
{

NSLog(@"Test");

}

モーダルビューコントローラが閉じられているのに、なぜこれらのどれも私の親ビューコントローラで機能しないのですか?どうすればこれを機能させることができますか?

4

2 に答える 2

130

この回答は、3つの最も重要なアプローチを説明するために書き直され/拡張されました(@galambalazs

1.ブロック

最も簡単なアプローチは、コールバックを使用すること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.委任

DelegationAppleが推奨するパターンは次のとおりです。

提示されたViewControllerを閉じる

提示されたViewControllerが提示されたViewControllerにデータを返す必要がある場合は、委任デザインパターンを使用して転送を容易にします。委任により、アプリのさまざまな部分でビューコントローラーを簡単に再利用できます。委任を使用すると、提示されたView Controllerは、正式なプロトコルからのメソッドを実装する委任オブジェクトへの参照を格納します。結果を収集すると、提示されたViewControllerはデリゲートでそれらのメソッドを呼び出します。典型的な実装では、提示するView Controllerは、それ自体を提示されたViewControllerのデリゲートにします。

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 didDismissViewController: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];
}

お役に立てれば!

于 2012-04-30T16:57:22.713 に答える
10

モーダルビューは、親にそれを却下するように指示する必要があります。そうすれば、親は却下を行う責任があるため、親はそれを知ることができます。

この例は、新しいプロジェクトを作成してUtility Applicationテンプレートを選択した場合に見られます。

于 2012-04-30T16:36:21.850 に答える