2

의 대리자 메서드 호출을 잡기. scrollViewDidScroll과 같은 자체 대리자 메서드에 응답 할 수 있기를 원하지만 동시에 대리자가 정상적으로 설정되도록하십시오. 대리자 속성을 방해하지 않지만 하위 클래스가 자체 대리자 호출에 응답 할 수있게하려면 어떻게해야합니까? 만 관심이있는 경우내가있는 UIScrollView의 하위 클래스를 만들 수 있습니다</p> <p>있는 UIScrollView의 관점에서이 문제를 설명하기 위해 시도 할 수 있습니다 원래 서브 클래스

+0

당신은 사용자 정의있는 UIScrollView에 두 번째 대리자를 추가 할 수 있습니다, 즉 그것의 방법을 소유 트리거입니다. – Larme

+0

@Larme 의견을 보내 주셔서 감사합니다. 그러나 그것이 제가 묻고있는 것과 정확히 일치하지 않습니다. 불명확하면 죄송합니다. 위임 클래스가 UIScrollViewDelegate가 제공해야하는 모든 대리자 메서드를 구현할 수 있기를 바랍니다. 하지만 일부 델리게이트 메소드에 대해서도 "듣기"를 원합니다. 하위 클래스에있는 모든 델리게이트 메소드를 구현하지 않아도되고, 그래서 자신의 델리게이트로 선언 할 수 있습니다. – Nathan

+0

[UIScrollView를 서브 클래스 화하고 대리자 속성을 비공개로 만드는 방법] 가능한 복제본 (http://stackoverflow.com/questions/9978279/how-to-subclass-uiscrollview-and-make-the-delegate-property-private) –

답변

2

시간이 좀 걸리지 만 원하는 것을 얻을 수 있습니다.

가 나는 방법 forwardInvocation:의 구현을 추가 한

편집 //. 이 메소드는 객체가 전송 된 메시지를 인식하지 못하면 객체에서 호출됩니다.

UIScrollView 대리자의 메서드 중 일부가 호출되고 하위 클래스가 호출 된 메서드를 구현하지 않으면이 경우 forwardInvocation이 호출됩니다. 이 메서드는 호출 된 selector가 UIScrollViewDelegate 프로토콜의 일부인지 확인합니다. '예'인 경우 클래스의 '참'대리자가이 선택기에 응답하면 호출 된 선택기의 호출을 사용자 지정 대리자로 전달합니다.

즉,이 솔루션을 사용하면 서브 클래스에 UIScrollViewDelegate 프로토콜의 모든 메소드를 구현할 필요가 없습니다. ScrollView의 하위 클래스에서 구현 된 메서드 실행은 하위 클래스의 '실제'대리자에게 전달됩니다.

예 :

#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 
+0

이 방법은 좋지만 UIScrollViewDelegate 프로토콜을 확장하는 새로운 프로토콜을 사용하여 선택기 작업에 응답 할 수 있습니다. 'customDelegate'는이 새로운 프로토콜을 따르며, 객체가 새로운 프로토콜을 따르는 경우에만'setDelegate'에서 설정됩니다. –

+0

예, 이것이 제 해결책이었습니다. 누군가 다른 사람도 그렇게 생각했기 때문에 기쁩니다. 그러나 나는 더 좋은 방법이 있어야한다고 생각하고 있었다. – Nathan

+0

답변을 업데이트했습니다. 원하는 결과를 얻으려면 코드가 적게 필요합니다. –

3

에 대한 scrollViewDidScroll, 단지 layoutSubviews를 오버라이드 (override) :

- (void)layoutSubviews { 
    [super layoutSubviews]; 

    // your code here 
} 

UIScrollView 그냥 그 대리인에게 scrollViewDidScroll:를 보내기 전에 자체 layoutSubviews를 보냅니다.

+0

Sweet !!, 나는 그것에 대해 생각하지 않았다. 이것은 실제로 scrollViewDidScroll 정확히, 감사 필요한대로 작동합니다. 그러나 실제로 질문에 대답하지 않기 때문에 대답으로 표시해야한다고 생각하지 않습니다. 죄송합니다 – Nathan

관련 문제