关闭模态视图控制器后刷新父视图控制器

11
在我的iOS应用程序中,用户可以从列表中选择一张图片,然后会弹出一个模态框,其中包含该图片和删除图片的选项。如果用户选择删除图片,则返回到原始视图控制器,其中包含图片列表。然后我需要刷新原始视图控制器以考虑已删除的图片。
我尝试使用NSNotificationCenter广播删除图像时向父视图控制器发送数据。但是,似乎没有接收到广播。
有没有其他方法:
1. 在模态框关闭后将数据发送回父视图控制器 2. 检测模态框何时从父视图控制器关闭
(我尝试按照这里中概述的示例操作,但似乎没有起作用)
以下是我的代码:
EditStepViewController(原始视图控制器):
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
MediaPreviewViewController *mediaPreviewVC = (MediaPreviewViewController *)[storyboard instantiateViewControllerWithIdentifier:@"MediaPreviewViewController"];
mediaPreviewVC.selectedImageURL = [NSString stringWithFormat:@"%@",gestureRecognizer.view.tag];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:mediaPreviewVC];
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(didDismissMediaPreview)
                                             name:@"MediaPreviewDismissed"
                                           object:nil];
[self presentViewController:navigationController animated:YES completion:nil];

MediaPreviewViewController(第二个视图控制器):

 ...
 [self deleteImage];
 [[NSNotificationCenter defaultCenter] postNotificationName:@"MediaPreviewDismissed" object:nil userInfo:nil];
 [self dismissViewControllerAnimated:YES completion:^(){
   NSLog(@"dismissed controller");
  }];

然后,在EditStepViewController中:
-(void)didDismissMediaPreview{
    NSLog(@"dismissed media preview"); // this is never logged!
    [self.view setNeedsDisplay]; // refresh view to account for deleted image
}

感谢您的帮助!


你能告诉我在哪里添加了观察者吗? - kshitij godara
3个回答

19

在我的情况下,我通常在这里使用代码块。

例如,你有一个ParentViewController.h文件。

@interface ParentViewController : UIViewController
@end

实现ParentViewController.m

// INCLUDE HERE THE MODAL CONTROLLER TO HAVE ACCESS TO ITS PUBLIC PROPERTY
#import ModalViewController.h

@implementation ParentViewController

// implement your modal dismiss block here
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
   // DEFINE HERE THE CALLBACK FUNCTION
   // 1. get the model view controller
   ModalViewController *mvc = [segue destinationViewController];

   // 2. Your code after the modal view dismisses
   mvc.onDismiss = ^(UIViewController *sender, NSObject *objectFromModalViewController)
   {
       // Do your stuff after dismissing the modal view controller
       .
       .
       .
   }
} 
@end

而且,ModalViewController.h

@interface ModalViewController : UIViewController

// call back function, a block
@property (nonatomic, strong) void (^onDismiss)(UIViewController *sender, NSObject *objectYouWantToPassBackToParentController)
@end

ModalViewController.m

@implementation ModalViewController

.
.
.

// your dismiss function say
- (IBAction)dismissViewController:(id)sender
{
   ... 

   [self deleteImage];

   [self dismissViewControllerAnimated:YES completion:^
   {
      // MAKE THIS CALL
      self.onDismiss(self, theOjectYouWantToPassBackToParentVC);
   }];
}
@end

1
这可能对那些在UIPopovePresentationController上遇到相同问题的人有所帮助。从我的经验来看,Allan的答案也可以解决相同的问题。
我刚刚遇到了一个问题,即作为UIPopoverPresentingController呈现的Viewcontroller的委托没有将调用发送到其根视图。而Allan的答案可以解决这个问题。
我的示例代码:
-(IBAction)choosePic:(id)sender
{
    UIButton *picButton = (UIButton *)sender;

    // Set PopoverPresentation view controller

    PicViewController *picVC = [self.storyboard instantiateViewControllerWithIdentifier:@"PicViewController"];

    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:picVC];

    picVC.preferredContentSize = CGSizeMake(500., 500.);


    // Set this function as described in Allan's answer

    picVC.dismissPopover = ^(UIViewController *controller, UIImage *image) 
    {

       _myImage = image;

       .....

       .....

       .....

    };

    navController.modalPresentationStyle = UIModalPresentationPopover;

    _picPopover = navController.popoverPresentationController;

    _picPopover.delegate = self;

    _picPopover.sourceView = self.view;

    _picPopover.sourceRect = [picButton frame];

    navController.modalPresentationStyle = UIModalPresentationPopover;

    navController.navigationBarHidden = YES;

    [self presentViewController:navController animated:YES completion:nil];

}

1
你应该在MediaPreviewViewController中创建一个协议。然后,在图像被删除时,发送一个委托方法,以便父视图控制器可以处理它。
此外,你也不应该让视图控制器自行解除(虽然可能性是有的,但建议创建模态的视图也负责移除模态...)
所以你应该得到类似于这样的东西:
在MediaPreviewViewController.h中:
@protocol MediaPreviewViewControllerDelegate <NSObject>

-(void)didRemovedImage;

@end

@interface MediaPreviewViewController : NSObject {
    id< MediaPreviewViewControllerDelegate > delegate;
}

@property (nonatomic, assign) id < MediaPreviewViewControllerDelegate> delegate;

在MediaPreviewViewController.m文件中:

@synthesize delegate = _delegate;

在MediaPreviewViewController中的您删除图像的方法中,只需要调用以下代码:
[_delegate didRemoveImage];

在您的父视图控制器中,您需要像使用委托一样实现此协议。然后,您也可以在此委托方法中从父视图中删除该视图。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接