2
votes

I can try to explain this in terms of a UIScrollView

I'll make a subclass of UIScrollView. I want to be able to respond to its own delegate methods such as scrollViewDidScroll but at the same time let the delegate get set as normal. How can I not interfere with the delegate property, but still have the subclass be able to respond to its own delegate calls?

2
You can add a second delegate to your custom UIScrollView, that's trigger its owns methods. - Larme
@Larme Thanks for the input, but that is not exactly what I'm asking, sorry if I'm unclear. I want the delegate class to be able to implement all the delegate methods that UIScrollViewDelegate has to offer. But I just want to also "listen in" on a select few delegate methods, I don't want to have to implement every delegate method in the subclass just so I can foreword them to its own delegate. - Nathan

2 Answers

3
votes

If you only care about scrollViewDidScroll, just override layoutSubviews:

- (void)layoutSubviews {
    [super layoutSubviews];

    // your code here
}

UIScrollView sends itself layoutSubviews just before sending scrollViewDidScroll: to its delegate.

2
votes

This will take some time but you can achieve what you want.

//EDITED

I have added implementation of the method forwardInvocation:. This method is invoked on object when object doesn't recognize message which was sent to it.

In our case when some of the UIScrollView delegate's methods will be called and our subclass and it doesn't implement called method, forwardInvocation will be called. This method checks whether called selector is part of the UIScrollViewDelegate protocol. If yes and if 'true' delegate of our class responds to this selector we forward invocation of called selector to our custom delegate.

That being said, using this solution you don't have to implement all methods of UIScrollViewDelegate protocol in your subclass. Execution of the methods which won;t be implemented in subclass of the ScrollView will be forwarded to 'true' delegate of our subclass.

Example:

#import <objc/runtime.h>

@protocol YourSubclassDelegate<UIScrollViewDelegate>
@end

 @interface YourSubclass ()
    @property (nonatomic, weak) id<YourSubclassDelegate> delegate;
 @end


@implementation 

//override delegate setter
- (void)setDelegate:(UIScrollViewDelegate)delegate
{
  self.customDelegate = delegate;
 [super setDelegate:self];
} 

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
   //do something you want
   if ([self.customDelegate respondsToSelector:@selector(scrollViewDidScroll:)]) {
      [self.customDelegate scrollViewDidScroll:self];
   }
}


- (id)forwardingTargetForSelector:(SEL)selector
{
   struct objc_method_description methodDescription = protocol_getMethodDescription(@protocol(UIScrollViewDelegate), selector, YES, YES);

   if(NULL != methodDescription.name) {
      if ([self.customDelegate respondsToSelector:selector]) {
        return self.customDelegate;
      }
   }

   return nil;
 }



@end