11

私の iOS アプリでは、ユーザーはリストから画像を選択できます。そのリストには、画像と画像を削除するオプションを含むモーダルが表示されます。ユーザーが画像の削除を選択すると、画像のリストを含む元の viewController に戻ります。次に、削除されたイメージを考慮して、元の ViewController を更新する必要があります。

NSNotificationCenter を使用して、画像が削除されたときに親 View Controller にブロードキャストしようとしました。ただし、ブロードキャストは受信されないようです。

他の方法はありますか

  1. モーダルが閉じられた後、データを親 ViewController に送り返します。
  2. モーダルが親 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 (2 番目の 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
}

よろしくお願いします。

4

3 に答える 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
于 2014-09-02T06:39:10.527 に答える
1

これは、UIPopovePresentationController で同じ問題を抱えている人を助けるかもしれません。私の経験から、アランの答えも同じ問題を解決できます。

UIPopoverPresentingController として存在する Viewcontroller のデリゲートについて問題がありましたが、そのルート ビューに呼び出しが送信されませんでした。そして、アランの答えはこの適合を解決することができます.

私のサンプルコード:

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

}
于 2015-02-02T07:17:39.480 に答える
1

MediaPreviewViewController でプロトコルを作成する必要があります。次に、画像が削除されたら、デリゲート メソッドを送信して、親ビューコントローラーがそれを処理できるようにします。

また、viewcontroller 自体を非表示にしないでください (可能ですが、モーダルを作成したビューもモーダルの削除を担当することをお勧めします...)。

したがって、次のようなものを取得する必要があります。

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

親ビューコントローラーでは、デリゲートで慣れているように、このプロトコルを実装する必要があります。その後、このデリゲート メソッドで親からビューを削除することもできます。

于 2014-09-02T06:44:15.923 に答える