我有一个名为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&#34; ToolbarView.h&#34;
@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。
更新:添加了更多代码
答案 0 :(得分:6)
在您的代码中,任何给定的DraggableToolbarView
实例都有两个属性来连接到委托,一个名为toolbarViewDelegate
,它从其超类继承,另一个名为{{1这是在draggableToolbarViewDelegate
本身中定义的。如果您希望控制器获取所有委托消息,您必须设置这两个。
然而,您正在尝试做的事情是可能的。您需要在两个视图类中使用相同的属性名称,以便任何实例只有一个委托连接。
首先,更改超类中委托的名称。 (请注意,您不需要也确实不应该为该属性声明一个ivar - 它是由DraggableToolbarView
创建的。)
@synthesize
您将在子类中使用相同的属性名称。
@interface ToolbarView : UIView <UIGestureRecognizerDelegate>
@property (nonatomic, assign) id <ToolbarViewDelegate> delegate;
@end
只要子类中的支持ivar的名称与超类的名称不同,就允许这样做,例如,
@interface DraggableToolbarView : ToolbarView
@property (nonatomic, assign) id <DraggableToolbarViewDelegate> delegate;
@end
现在更改两个视图类中的所有委托消息以使用这一个属性:
// 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:
,它将使用相同的委托来执行拖动方法和显示/隐藏方法。
最后,术语/解释性说明。在回应your previous question时,Caleb使用了正确的术语来表示“堆叠”协议,理查德则没有。协议不会继承,但一个协议可以采用另一个协议。这种关系是相似的,但却截然不同。当一个对象符合协议时,它承诺实现该协议中声明的方法。协议没有实现。采用另一种协议的协议也是如此 - 这两种方法都被宣布存在于两者中。当你写:
DraggableToolbarView
你说任何承诺实现@protocol DraggableToolbarViewDelegate <ToolbarViewDelegate>
方法的对象也会实现DraggableToolbarViewDelegate
中的方法。这就是它的意思。同样,没有实现伴随着这个承诺。
在这种情况下,这意味着ToolbarViewDelegate
可以指望其委托实施DraggableToolbarView
中的方法。
答案 1 :(得分:1)
你没有给出完整的代码,但是从这里的任何内容, 确保
id <ToolBarViewDelegate>
委托作为属性。