2012-05-26 66 views
5

我有一个叫做ToolbarView的类,它是UIView的一个子类,基本上创建了一个消失/重新出现的UIToolbar的UIView。我也有一个名为DraggableToolbarView的ToolbarView的子类,使用户可以在屏幕上拖动视图。试图实现委托继承

我需要为ToolbarView创建一个委托,以便它可以在工具栏重新出现和消失时通知另一个对象/类。我还需要为DraggableToolbarView创建一个委托,以便在拖动视图时通知另一个对象/类。当工具栏重新出现并消失时,DraggableToolbarViews委托还需要通知另一个对象/类。

所以我决定实现ToolbarViewDelegate,并DraggableToolbarViewDelegate从它继承,并有自己的方法,像以下:

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]; 
     } 

     ... 
} 

工具箱arViewDelegate.h

@class ToolbarView; 

@protocol ToolbarViewDelegate 

@required 

- (void) toolBarViewWillShowToolbar:(ToolbarView *)toolbarView; 
- (void) toolBarViewWillHideToolbar:(ToolbarView *)toolbarView; 

@end 

DraggableToolbarView.h

#进口 “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]它的作品。我已经尝试了每个委托单独进行而没有继承,它工作正常,所以我相信问题不在代码的任何其他部分。

任何人都知道为什么?我想通过使协议继承,我不必为DraggableToolbar对象设置ToolbarViewDelegate。

更新:增加了更多的代码

回答

6

在代码中,任何给定的DraggableToolbarView实例具有属性连接到代表,一个叫toolbarViewDelegate它从它的超类继承,和一个叫draggableToolbarViewDelegate这是在DraggableToolbarView定义本身。如果您希望控制器获取所有委托消息,则必须设置这两者。

但是,您正在尝试做的事情是可能的。您需要在两个视图类中使用相同的属性名称,以便任何实例只有一个委托连接。

首先,更改超类中委托的名称。 (请注意,你不需要,确实不应该打扰,申报伊娃的属性 - 它是由@synthesize创建。)

@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,它会使用相同的委托拖动方法和显示/喜de方法。

最后,一个术语/解释说明。作为对your previous question的回应,Caleb使用了“堆叠”协议的正确术语,而理查德没有。协议不互相继承,但一个协议可以采用另一个。这种关系是相似的,但是截然不同。当一个对象符合协议,它承诺实现在该协议中声明的方法。协议没有实现。一个协议采用另一个协议也是如此 - 这两种方法只是宣布存在。当你写:你说

@protocol DraggableToolbarViewDelegate <ToolbarViewDelegate> 

那这将实现DraggableToolbarViewDelegate的方法的任何对象也将从ToolbarViewDelegate实现的方法。这就是它的意思。再次,没有实现伴随着这个承诺。

在这种情况下,这意味着DraggableToolbarView可以期望其代表执行ToolbarViewDelegate中的方法。

+0

欣赏这个伟大的职位。想想我可能会坚持让代表独立,而不是命名事物的忠实粉丝。你通常会做什么或建议做什么? –

+0

很高兴我能帮到你。我没有看到覆盖委托属性的任何错误;它使代码的两边更清晰。 –

1

你还没有给整个代码,但无论是在这里, 确保

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