Pregunta

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?

¿Fue útil?

Solución 2

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

Otros consejos

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top