Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple delegates per one object?

I have a UIScrollView that I need to subclass and within the subclass I need to attach the UIScrollViewDelegate so I can implement the viewForZoomingInScrollView method.

Then I have a UIViewController where I need to instantiate an object of this UIScrollView subclass that I created, and I would also like to make the UIViewController a UIScrollViewDelegate for this object so I can implement scrollViewDidZoom in this UIViewController class.

How is it possible to make one object have two delegates? (I know I could easily just have one delegate and just implement both methods there, but for design purposes I'd like to do it the way that I'm mentioning).

like image 450
Ser Pounce Avatar asked Jan 25 '12 08:01

Ser Pounce


People also ask

Can a class have multiple delegates?

The delegate pattern is about a 1 to 1 relationship between a class and it's delegate. Whilst it is possible to achieve some level of multiple delegation through switching the delegates in and out, it's more likely to lead to unpredictable behaviour and bugs.

What is multicast delegate in Swift?

Multicast Delegate is a generic wrapper around yet another delegate protocol, that means it create one-to-many delegate relationships. This allows providing an object with an array of delegates.

Why we use delegates in C#?

Delegates allow methods to be passed as parameters. Delegates can be used to define callback methods. Delegates can be chained together; for example, multiple methods can be called on a single event. Methods don't have to match the delegate type exactly.

What is delegate in C#?

A delegate is an object which refers to a method or you can say it is a reference type variable that can hold a reference to the methods. Delegates in C# are similar to the function pointer in C/C++. It provides a way which tells which method is to be called when an event is triggered.


2 Answers

Sometimes it makes sense to attach several delegates to a scroll view. In that case you can build a simple delegation splitter:

// Public interface
@interface CCDelegateSplitter : NSObject

- (void) addDelegate: (id) delegate;
- (void) addDelegates: (NSArray*) delegates;

@end

// Private interface
@interface CCDelegateSplitter ()
@property(strong) NSMutableSet *delegates;
@end

@implementation CCDelegateSplitter

- (id) init
{
    self = [super init];
    _delegates = [NSMutableSet set];
    return self;
}

- (void) addDelegate: (id) delegate
{
    [_delegates addObject:delegate];
}

- (void) addDelegates: (NSArray*) delegates
{
    [_delegates addObjectsFromArray:delegates];
}

- (void) forwardInvocation: (NSInvocation*) invocation
{
    for (id delegate in _delegates) {
        [invocation invokeWithTarget:delegate];
    }
}

- (NSMethodSignature*) methodSignatureForSelector: (SEL) selector
{
    NSMethodSignature *our = [super methodSignatureForSelector:selector];
    NSMethodSignature *delegated = [(NSObject *)[_delegates anyObject] methodSignatureForSelector:selector];
    return our ? our : delegated;
}

- (BOOL) respondsToSelector: (SEL) selector
{
    return [[_delegates anyObject] respondsToSelector:selector];
}

@end

Then simply set an instance of this splitter as a delegate of the scroll view and attach any number of delegates to the splitter. All of them will receive the delegation events. Some caveats apply, for example all the delegates are assumed to be of the same type, otherwise you’ll have trouble with the naive respondsToSelector implementation. This is not a big problem, it’s easy to change the implementation to only send delegation events to those who support them.

like image 56
zoul Avatar answered Oct 11 '22 19:10

zoul


You don't want an object with 2 delegates. You want to keep your customScrollView keep the responsibility of its own UIScrollViewDelegate functions.

To make your parentVC respond to the delegate methods of UIScrollView as well you will have to make a custom delegate inside your customScrollView.

At the moment a UIScrollViewDelegate function gets called you will also call one of your delegate functions from your custom delegate. This way your parentVC will respond at the moment you want it to.

It will look somewhat like this.

CustomScrollView.h

@protocol CustomDelegate <NSObject>

//custom delegate methods
-(void)myCustomDelegateMethod;

@end

@interface CustomScrollView : UIScrollView <UIScrollViewDelegate>
{
    id<CustomDelegate> delegate
    //the rest of the stuff

CustomScrollView.m

-(void) viewForZoomingInScrollView
{
    [self.delegate myCustomDelegateMethod];
    //rest of viewForZoomingInScrollView code

ParentVC.h

@interface CustomScrollView : UIViewController <CustomDelegate>
{
    //stuff

ParentVC.m

-(void)makeCustomScrollView
{
     CustomScrollView *csv = [[CustomScrollView alloc] init];
     csv.delegate = self;
     //other stuff

}

-(void)myCustomDelegateMethod
{
   //respond to viewForZoomingInScrollView
}

I hope this fully covers your problem. Good luck.

like image 29
Totumus Maximus Avatar answered Oct 11 '22 20:10

Totumus Maximus