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。如果您只有一个侦听器(父视图控制器)对解雇感兴趣,这很好。您甚至可以通过事件传递一些数据。

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 推荐的模式:

关闭呈现的视图控制器

如果呈现的视图控制器必须向呈现的视图控制器返回数据,请使用委托设计模式来促进传输。委托使在应用程序的不同部分重用视图控制器变得更加容易。通过委托,呈现的视图控制器存储对委托对象的引用,该委托对象实现了正式协议中的方法。当它收集结果时,呈现的视图控制器在其委托上调用这些方法。在典型的实现中,呈现视图控制器使自己成为其呈现视图控制器的代表。

主视图控制器

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.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 回答