在原始子类中捕获委托方法调用

时间:2014-03-06 18:26:59

标签: objective-c uiscrollview delegates nsobject uiscrollviewdelegate

我可以尝试用UIScrollView来解释这个问题

我将创建UIScrollView的子类。我希望能够响应自己的委托方法,如scrollViewDidScroll,但同时让委托设置为正常。我怎么能不干涉委托属性,但仍然有子类能够响应自己的委托调用?

2 个答案:

答案 0 :(得分:3)

如果您只关心scrollViewDidScroll,请覆盖layoutSubviews

- (void)layoutSubviews {
    [super layoutSubviews];

    // your code here
}

UIScrollView在将layoutSubviews发送给其代理人之前发送自己scrollViewDidScroll:

答案 1 :(得分:2)

这需要一些时间,但你可以达到你想要的效果。

<强> // EDITED

我添加了方法forwardInvocation:的实现。当对象无法识别发送给它的消息时,将在对象上调用此方法。

在我们的情况下,当调用某些UIScrollView委托的方法而我们的子类并且它没有实现被调用的方法时,将调用forwardInvocation。此方法检查被调用的选择器是否是UIScrollViewDelegate协议的一部分。如果是,如果我们的类的'true'委托响应这个选择器,我们将被调用的选择器调用到我们的自定义委托。

话虽这么说,使用此解决方案,您不必在子类中实现UIScrollViewDelegate协议的所有方法。在ScrollView的子类中实现的方法的执行将被转发到我们子类的'true'委托。

示例:

#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