Ser*_*nce 5 iphone cocoa-touch delegates design-patterns ios
我有一个名为ToolbarView的类,它是UIView的子类,基本上创建了一个UIView,它顶部有一个消失/重新出现的UIToolbar.我还有一个名为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];
        }
        ...
}
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]时候.我已经尝试单独执行每个委托没有继承,它工作正常,所以我认为问题不在代码的任何其他部分.
有谁可能知道为什么?我认为通过使协议继承,我不必为DraggableToolbar对象设置ToolbarViewDelegate.
更新:添加了更多代码
在您的代码中,任何给定的DraggableToolbarView实例都有两个连接到委托的属性,一个叫做toolbarViewDelegate它从超类继承,另一个叫做自己draggableToolbarViewDelegate定义DraggableToolbarView.如果您希望控制器获取所有委托消息,则必须设置这两个.
但是,你正在努力做的事情是可能的.您需要在两个视图类中使用相同的属性名称,以便任何实例只有一个委托连接.
首先,更改超类中委托的名称.(请注意,您不需要也确实不应该为该属性声明一个ivar  - 它是由@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:到a DraggableToolbarView,它将使用相同的委托来进行拖动方法和显示/隐藏方法.
最后,术语/解释性说明.在回答您之前提出的问题时,Caleb使用了正确的术语来表示"堆叠"协议,理查德则没有.协议不会相互继承,但一种协议可以采用另一种协议.这种关系是相似的,但却截然不同.当一个对象符合协议时,它承诺实现该协议中声明的方法.协议没有实现.采用另一种协议的协议也是如此 - 这两种方法都被宣布存在于两者中.当你写:
@protocol DraggableToolbarViewDelegate <ToolbarViewDelegate>
你说任何承诺实现DraggableToolbarViewDelegate方法的对象也会实现方法ToolbarViewDelegate.这就是它的意思.同样,没有实现伴随着这个承诺.
在这种情况下,这意味着a DraggableToolbarView可以期望其委托实现方法ToolbarViewDelegate.
| 归档时间: | 
 | 
| 查看次数: | 2335 次 | 
| 最近记录: |