试图实现委托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的方法。

你没有给出完整的代码,但从这里的任何东西,请确保

  1. 您的ToolBarView及其子类具有一个id <ToolBarViewDelegate>委托作为属性。
  2. 你的DraggableToolbarViewDelegate扩展NSObject协议。
  3. 和你的其他ViewController对象符合委托协议,而不是toolbarview。
  4. 一旦你的控制器给出委托方法的实现并且符合协议,把view的委托对象设置为self,然后使用视图中设置的委托属性来调用这些协议方法。