Подтвердить что ты не робот

Обновление родительского ViewController после отклонения ModalViewController

В моем приложении iOS пользователь может выбрать изображение из списка, на котором им будет представлен модальный код, содержащий изображение и параметры для удаления изображения. Если пользователь хочет удалить изображение, она возвращается в исходный viewController, содержащий список изображений. Мне нужно затем обновить исходный ViewController, чтобы принять во внимание удаленное изображение.

Я попытался использовать NSNotificationCenter для трансляции, когда изображение будет удалено в родительский View Controller. Однако похоже, что трансляция так и не была получена.

Есть ли другой способ

  • отправить данные обратно в родительский ViewController после отклонения модальности и
  • обнаруживает, когда модаль отклоняется из родительского ViewController?

(я попробовал следующий пример здесь, но он не работал)

Ниже мой код:

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 (второй ViewController):

 ...
 [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
}

Заранее благодарим за помощь!

4b9b3361

Ответ 1

В моем случае я обычно использую блок здесь.

Например, у вас есть 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

Ответ 2

Вы должны сделать протокол в своем 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];

В вашем родительском контроллере представления вам необходимо реализовать этот протокол, как вы привыкли с делегатами. Затем вы также можете удалить представление из родительского объекта в этом делетете

Ответ 3

Это может помочь любому, у кого такая же проблема, в UIPopovePresentationController. По моему опыту, ответ Аллана может решить ту же проблему.

У меня только проблема с делегатом Viewcontroller, который присутствует, поскольку UIPopoverPresentingController не отправил вызов в свой корневой вид. И ответ Аллана может решить эту проблему.

Мой пример кода:

-(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 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];

}