Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

simplifying delegate scheme with blocks - is it possible in this context?

Tags:

ios

iphone

block

I have read so many positive things about using blocks - in particular that it simplifys the code by elimanting delegate calls. I have found examples where blocks are used at end of animation instead of delegate calls - there I understand how it can be done.

But I would really like to know if the cumbersome scheme of having to use delegates when presenting and dismissing viewcontrollers can also be simplified with blocks.

The standard recommended way to display and dismiss scheme looks like this, where in VC1 a new VC2 is presented which is dismissed by the delegate in VC1 again.

  VC2 *vc2 = [[VC2 alloc] initWithNibName:@"VC2" bundle:nil ];
  vc2.delegate = self; 
  [self presentModalViewController: vc2 animated: YES]; // or however you present your VC2

Withis VC2 returning to vc1:

[self.delegate vc2HasFinished];

For this to work one has to create a protocol like this: in VC2Protocol.h file

 @protocol VC2Protocol <NSObject>
    -(void)vc2HasFinished;
    @end

Then include this VC2Protocol.h in VC1 and VC2. In VC1 one has to define this method like this:

-(void) weitereRufNrVCDidFinish{
    [self dismissModalViewControllerAnimated:YES completion: nil];

}

Would really be nice if one can write more concise code, avoiding having to declare a protocol just for that.

Thanks!

like image 752
user387184 Avatar asked Feb 20 '23 07:02

user387184


1 Answers

For the case of dismissing a modally presented vc, please be aware that the vc can dismiss itself. So instead of [self.delegate vc2HasFinished]; you can just say [self dismissModalViewControllerAnimated:YES completion: nil]; within vc2.

But I agree with you that blocks useful and delegates are clumsy (and more error prone, especially pre-ARC). So here's how you can replace delegate callbacks in a vc. Let's invent a situation where the vc would want to tell it's delegate something, say for example, that it just fetched an image...

// vc2.h
@property (nonatomic, copy) void (^whenYouFetchAnImage)(UIImage *);
// note, no delegate property here

// vc2.m
// with your other synthesizes
@synthesize whenYouFetchAnImage=_whenYouFetchAnImage;

// when the image is fetched
self.whenYouFetchAnImage(theFetchedImage);

The presenting vc doesn't set a delegate, but it does give the new vc some code to run (in it's own execution context) when an image is fetched...

// presenting vc.m
VC2 *vc2 = [[VC2 alloc] initWithNibName:@"VC2" bundle:nil];

// say this presenting vc has an image view that will show the image fetched
// by vc2.  (not totally plausible since this image view will probably be covered by vc2
// when the block is invoked)
vc2.whenYouFetchAnImage = ^(UIImage *image) { self.myImageView.image = image; };
like image 58
danh Avatar answered May 07 '23 09:05

danh