试图实现委托inheritance
我有一个叫做ToolbarView的类,它是UIView的一个子类,基本上创build了一个消失/重新出现的UIToolbar的UIView。 我也有ToolbarView的子类DraggableToolbarView使用户能够拖动屏幕周围的视图。
我需要为ToolbarView创build一个委托,以便在工具栏重新出现和消失时通知另一个对象/类。 我还需要为DraggableToolbarView
创build一个委托,以便在拖动视图时通知另一个对象/类。 DraggableToolbarViews委托也将需要通知另一个对象/类的工具栏重新出现和消失。
所以我决定实现ToolbarViewDelegate,并从中inheritanceDraggableToolbarViewDelegate,并拥有如下的方法:
ToolbarView.h
#import <UIKit/UIKit.h> @protocol ToolbarViewDelegate; @interface ToolbarView : UIView <UIGestureRecognizerDelegate> { id <ToolbarViewDelegate> _toolbarViewDelegate; } @property(nonatomic, assign) id <ToolbarViewDelegate> toolbarViewDelegate; @end
ToolbarView.m
#import "ToolbarView.h" #import "ToolbarViewDelegate.h" ... - (void) showBars { ... if (self.toolbarViewDelegate) { [self.toolbarViewDelegate toolbarViewWillShowToolbar:self]; } ... } - (void) hideBars { ... if (self.toolbarViewDelegate) { [self.toolbarViewDelegate toolbarViewWillHideToolbar:self]; } ... }
ToolbarViewDelegate.h
@class ToolbarView; @protocol ToolbarViewDelegate @required - (void) toolBarViewWillShowToolbar:(ToolbarView *)toolbarView; - (void) toolBarViewWillHideToolbar:(ToolbarView *)toolbarView; @end
DraggableToolbarView.h
#import“ToolbarView.h”
@protocol DraggableToolbarViewDelegate; @interface DraggableToolbarView : ToolbarView { id <DraggableToolbarViewDelegate> _draggableToolbarViewDelegate; } @property(nonatomic, assign) id <DraggableToolbarViewDelegate> draggableToolbarViewDelegate; @end
DraggableToolbarView.m
#import "DraggableToolbarView.h" #import "DraggableToolbarViewDelegate.h" ... - (void)drag:(UIPanGestureRecognizer *)sender { ... if (self.draggableToolbarViewDelegate) { [self.draggableToolbarViewDelegate draggableToolbarViewWillDrag:self]; } ... } ...
DraggableToolbarViewDelegate.h
#import "ToolbarViewDelegate.h" @class DraggableToolbarView; @protocol DraggableToolbarViewDelegate <ToolbarViewDelegate> @required - (void) draggableToolbarViewWillDrag:(DraggableToolbarView *)draggableToolbarView; @end
SomeViewController.h
#import <UIKit/UIKit.h> #import "ToolbarViewDelegate.h" #import "DraggableToolbarViewDelegate.h" @interface SomeViewController : UIViewController <ToolbarViewDelegate, DraggableToolbarViewDelegate> { } @end
SomeViewController.m
#import "DraggableToolbarView.h" ... - (void) toolbarViewWillShowToolbar:(ToolbarView*)toolbarView { //NSLog(@"Toolbar Showed"); } - (void) toolbarViewWillHideToolbar:(ToolbarView*)toolbarView { //NSLog(@"Toolbar Hidden"); } - (void) draggableToolbarViewWillDrag:(DraggableToolbarView*)draggableToolbarView { //NSLog(@"Dragged"); } ... [draggableToolbarView setDraggableToolbarViewDelegate:self]; ...
当我这样做时,只有DraggableToolbarDelegate
方法正在响应。 但是当我也做[drabbleToolbarView setToolbarViewDelegate:self]
它的作品。 我试着做每个委托没有inheritence分开,它工作正常,所以我相信这个问题不在代码的任何其他部分。
任何人都知道为什么? 我想通过使协议inheritance,我也不必为DraggableToolbar对象设置ToolbarViewDelegate。
更新:添加了更多的代码
在你的代码中,任何给定的DraggableToolbarView
实例都有两个连接委托的属性,一个叫做toolbarViewDelegate
,它从它的toolbarViewDelegate
类inheritance而来,另一个叫toolbarViewDelegate
,在DraggableToolbarView
定义。 如果要让控制器获取所有委托消息,则必须设置这两者。
然而,你正在尝试做的事情是可能的。 您需要在两个视图类中使用相同的属性名称,以便任何实例只有一个委托连接。
首先,改变超类中委托的名字。 (请注意,您不需要,也不必费心去为属性声明一个ivar,它是由@synthesize
创build的。)
@interface ToolbarView : UIView <UIGestureRecognizerDelegate> @property (nonatomic, assign) id <ToolbarViewDelegate> delegate; @end
您将在子类中使用相同的属性名称。
@interface DraggableToolbarView : ToolbarView @property (nonatomic, assign) id <DraggableToolbarViewDelegate> delegate; @end
只要子类中支持ivar的名称与超类的名称不同,就可以这样做,
// In superclass @synthesize delegate; // In subclass @synthesize delegate = delegate_;
现在改变两个视图类中的所有委托消息来使用这个属性:
- (void)showBars { if (self.delegate) { [self.delegate ... - (void)drag:(UIPanGestureRecognizer *)sender { //... if (self.delegate) { [self.delegate ...
现在你可以发送setDelegate:
到一个DraggableToolbarView
,它将使用拖动方法和显示/隐藏方法相同的委托。
最后是一个术语/解释性说明。 在回答你之前的问题时 ,迦勒使用了正确的术语来表示“堆叠”协议,理查德则没有。 协议不会彼此inheritance ,但一个协议可以采用另一个协议。 这种关系是相似的,但是有区别的。 当一个对象符合协议时,它承诺实现该协议中声明的方法。 协议没有实现。 一个协议采用另一协议也是如此 – 这两种方法只是宣布存在。 当你写:
@protocol DraggableToolbarViewDelegate <ToolbarViewDelegate>
你是说任何承诺实现DraggableToolbarViewDelegate
的方法的对象也将实现从ToolbarViewDelegate
的方法。 这就是这个意思。 再次,没有实现与这个承诺一起。
在这种情况下,这意味着DraggableToolbarView
可以期望它的委托实现ToolbarViewDelegate
的方法。
你没有给出完整的代码,但从这里的任何东西,请确保
- 您的ToolBarView及其子类具有一个
id <ToolBarViewDelegate>
委托作为属性。 - 你的DraggableToolbarViewDelegate扩展NSObject协议。
- 和你的其他ViewController对象符合委托协议,而不是toolbarview。
- 一旦你的控制器给出委托方法的实现并且符合协议,把view的委托对象设置为self,然后使用视图中设置的委托属性来调用这些协议方法。