How to subclass UIScrollView and make the delegate property private

前端 未结 5 1051
悲&欢浪女
悲&欢浪女 2020-12-04 09:03

Here is what I want to achieve:

I want to subclass an UIScrollView to have additional functionality. This subclass should be able to react on scrolling, so i have to

5条回答
  •  孤城傲影
    2020-12-04 09:44

    Thanks @robmayoff I encapsulated to be a more generic delegate interceptor: Having original MessageInterceptor class:

    MessageInterceptor.h

    @interface MessageInterceptor : NSObject
    
    @property (nonatomic, assign) id receiver;
    @property (nonatomic, assign) id middleMan;
    
    @end
    

    MessageInterceptor.m

    @implementation MessageInterceptor
    
    - (id)forwardingTargetForSelector:(SEL)aSelector {
        if ([self.middleMan respondsToSelector:aSelector]) { return    self.middleMan; }
        if ([self.receiver respondsToSelector:aSelector]) { return self.receiver; }
        return [super forwardingTargetForSelector:aSelector];
    }
    
    - (BOOL)respondsToSelector:(SEL)aSelector {
        if ([self.middleMan respondsToSelector:aSelector]) { return YES; }
        if ([self.receiver respondsToSelector:aSelector]) { return YES; }
        return [super respondsToSelector:aSelector];
    }
    
    @end
    

    It is used in your generic delegate class:

    GenericDelegate.h

    @interface GenericDelegate : NSObject
    
    @property (nonatomic, strong) MessageInterceptor * delegate_interceptor;
    
    - (id)initWithDelegate:(id)delegate;
    
    @end
    

    GenericDelegate.m

    @implementation GenericDelegate
    
    - (id)initWithDelegate:(id)delegate {
        self = [super init];
        if (self) {
            self.delegate_interceptor = [[MessageInterceptor alloc] init];
            [self.delegate_interceptor setMiddleMan:self];
            [self.delegate_interceptor setReceiver:delegate];
        }
        return self;
    }
    
    // delegate methods I wanna override:
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        // 1. your custom code goes here
        NSLog(@"Intercepting scrollViewDidScroll: %f %f", scrollView.contentOffset.x, scrollView.contentOffset.y);
    
        // 2. forward to the delegate as usual
        if ([self.delegate_interceptor.receiver respondsToSelector:@selector(scrollViewDidScroll:)]) {
            [self.delegate_interceptor.receiver scrollViewDidScroll:scrollView];
        }
     }
    //other delegate functions you want to intercept
    ...
    

    So I can intercept any delegate I need to on any UITableView, UICollectionView, UIScrollView... :

    @property (strong, nonatomic) GenericDelegate *genericDelegate;
    @property (nonatomic, strong) UICollectionView* collectionView;
    
    //intercepting delegate in order to add separator line functionality on this scrollView
    self.genericDelegate = [[GenericDelegate alloc]initWithDelegate:self];
    self.collectionView.delegate = (id)self.genericDelegate.delegate_interceptor;
    
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        NSLog(@"Original scrollViewDidScroll: %f %f", scrollView.contentOffset.x, scrollView.contentOffset.y);
    }
    

    In this case UICollectionViewDelegate scrollViewDidScroll: function will be executed on our GenericDelegate (with any code we want to add) and on in the implementation of our own class

    Thats my 5 cents, thanks to @robmayoff and @jhabbott previous answer

提交回复
热议问题