每个对象有多个代表?
我有一个UIScrollView
,我需要子类和子类内我需要附加UIScrollViewDelegate
所以我可以实现viewForZoomingInScrollView
方法。
然后我有一个UIViewController
,我需要实例化我创build的这个UIScrollView
子类的一个对象,我也想使UIViewController成为这个对象的UIScrollViewDelegate
,所以我可以在这个UIViewController
类中实现scrollViewDidZoom
。
如何使一个对象有两个代表? (我知道我可以很容易地只有一个委托,只是在那里实现这两个方法,但为了devise的目的,我想按照我提到的方式来做)。
你不想要一个2代表的对象。 你想保持你的customScrollView保持自己的UIScrollViewDelegate函数的责任。
为了让你的父VC对UIScrollView的委托方法作出响应,你必须在你的customScrollView里面做一个自定义委托。
在调用UIScrollViewDelegate函数的同时,您还将调用您的自定义委托中的一个委托函数。 这样你的父VC会在你想要的时候做出响应。
它看起来有点像这样。
CustomScrollView.h
@protocol CustomDelegate <NSObject> //custom delegate methods -(void)myCustomDelegateMethod; @end @interface CustomScrollView : UIScrollView <UIScrollViewDelegate> { id<CustomDelegate> delegate //the rest of the stuff
CustomScrollView.m
-(void) viewForZoomingInScrollView { [self.delegate myCustomDelegateMethod]; //rest of viewForZoomingInScrollView code
ParentVC.h
@interface CustomScrollView : UIViewController <CustomDelegate> { //stuff
ParentVC.m
-(void)makeCustomScrollView { CustomScrollView *csv = [[CustomScrollView alloc] init]; csv.delegate = self; //other stuff } -(void)myCustomDelegateMethod { //respond to viewForZoomingInScrollView }
我希望这完全覆盖你的问题。 祝你好运。
有时将多个代表附加到滚动视图是有意义的。 在这种情况下,您可以构build一个简单的委托拆分器:
// Public interface @interface CCDelegateSplitter : NSObject - (void) addDelegate: (id) delegate; - (void) addDelegates: (NSArray*) delegates; @end // Private interface @interface CCDelegateSplitter () @property(strong) NSMutableSet *delegates; @end @implementation CCDelegateSplitter - (id) init { self = [super init]; _delegates = [NSMutableSet set]; return self; } - (void) addDelegate: (id) delegate { [_delegates addObject:delegate]; } - (void) addDelegates: (NSArray*) delegates { [_delegates addObjectsFromArray:delegates]; } - (void) forwardInvocation: (NSInvocation*) invocation { for (id delegate in _delegates) { [invocation invokeWithTarget:delegate]; } } - (NSMethodSignature*) methodSignatureForSelector: (SEL) selector { NSMethodSignature *our = [super methodSignatureForSelector:selector]; NSMethodSignature *delegated = [(NSObject *)[_delegates anyObject] methodSignatureForSelector:selector]; return our ? our : delegated; } - (BOOL) respondsToSelector: (SEL) selector { return [[_delegates anyObject] respondsToSelector:selector]; } @end
然后,简单地将此分离器的实例设置为滚动视图的委托,并将任意数目的代表附加到分离器。 他们都会收到代表团的活动。 有些注意事项是适用的,例如所有代表被假定为相同的types,否则你将遇到天真的respondsToSelector
实现的麻烦。 这不是一个大问题,很容易将实现更改为仅向支持它们的用户发送委派事件。
简短的回答:你不。 代表通常是弱一对一的关系:
@property (nonatomic, weak /*or assign*/) id<MyViewDelegate> delegate;
有时你会看到一个“倾听者”的devise模式,这是代表的一对多forms:
- (void) addListener:(id<MyViewListener>)listener; - (void) removeListener:(id<MyViewListener>)listener;
在你的情况下,UIScrollView中似乎没有一个好的公共覆盖点,允许子类指定viewForZoomingInScrollView。 如果可能的话,我会避免让UIScrollView成为它自己的委托。 你可以使UIViewController成为UIScrollViewDelegate并让它提供viewForZooming。 或者你可以做一个中间视图的子类,它使用UIScrollView,提供viewForZooming,并转发其他委托方法。
我不认为你可以有两个UIScrollViewDelegate
委托直接连接到同一个对象。
你可以做的是让两个代表连锁在一起。 也就是说,你将一个委托人连接到另一个委托人,当它不能直接处理它们时,就把前一个委托人连接到另一个委托人。
无论如何,我想我缺less一点点来充分提出一个解决scheme,即你为什么需要第二个委托,不能总是通过一个委托。 换句话说,我认为可能会有其他devise可以避免需要两名代表。
这是一个优雅的解决scheme,涉及2个代表:
-
自定义滚动视图类LTInfiniteScrollView子类
UIView
(不是UIScrollView
),并添加一个UIScrollView
作为一个孩子。 LTInfiniteScrollView将自己设置为这个UIScrollView
的委托。 -
LTInfiniteScrollView定义了它自己的
delegate
属性和协议。 由于LTInfiniteScrollView没有UIScrollView
子类,因此没有与之冲突的现有delegate
属性。