尝试实现委托继承 [英] Trying to Implement Delegate Inheritance

查看:128
本文介绍了尝试实现委托继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为ToolbarView的类,它是UIView的子类,基本上创建一个UIView,在顶部有一个消失/重现的UIToolbar。我还有一个ToolbarView的子类,名为DraggableToolbarView,使用户可以在屏幕上拖动视图。



我需要为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 / p>

  #importToolbarView.h
#importToolbarViewDelegate.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 / p>

#importToolbarView.h

  @protocol DraggableToolbarViewDelegate; 

@interface DraggableToolbarView:ToolbarView
{
id< DraggableToolbarViewDelegate> _draggableToolbarViewDelegate;
}

@property(nonatomic,assign)id< DraggableToolbarViewDelegate> draggableToolbarViewDelegate;

@end

DraggableToolbarView.m / p>

  #importDraggableToolbarView.h
#importDraggableToolbarViewDelegate.h

。 ..

- (void)drag:(UIPanGestureRecognizer *)sender
{
...
if(self.draggableToolbarViewDelegate)
{
[self.draggableToolbarViewDelegate draggableToolbarViewWillDrag:self];
}

...

}

...

DraggableToolbarViewDelegate.h

  importToolbarViewDelegate.h

@class DraggableToolbarView;

@protocol DraggableToolbarViewDelegate< ToolbarViewDelegate>

@required

- (void)draggableToolbarViewWillDrag:(DraggableToolbarView *)draggableToolbarView;

@end

SomeViewController.h / p>

  #import< UIKit / UIKit.h> 
#importToolbarViewDelegate.h
#importDraggableToolbarViewDelegate.h

@interface SomeViewController:UIViewController< ToolbarViewDelegate,DraggableToolbarViewDelegate>
{

}
@end

strong> SomeViewController.m

  #importDraggableToolbarView.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>代表;
@end

您将在子类中使用相同的属性名称。

  @interface DraggableToolbarView:ToolbarView 
@property(nonatomic,assign)id< DraggableToolbarViewDelegate>代表;
@end

这是允许的,只要子类中的背景ivar的名称不同于超类,例如

  //在超类中
@synthesize delegate;
//在子类中
@synthesize delegate = delegate_;

现在更改两个视图类中的所有委托消息,以使用此一个属性:

   - (void)showBars 
{

if(self.delegate)
{
[self.delegate ...

- (void)drag:(UIPanGestureRecognizer *)sender
{
// ...
if .delegate)
{
[self.delegate ...

可以将 setDelegate:发送到 DraggableToolbarView ,并且它将使用相同的委托来执行拖动方法和显示/隐藏方法。



最后,一个术语/解释性说明。为了回应您之前的问题,Caleb对堆叠协议使用了正确的术语,理查德不。协议不会彼此继承,但一个协议可以采用另一个协议。关系是相似的,但不同。当对象符合协议时,它承诺实现该协议中声明的方法。协议没有实现。一个协议采用另一个协议同样如此 - 这些方法只是声明存在于两者中。写入时:

  @protocol DraggableToolbarViewDelegate< ToolbarViewDelegate> 

你说的任何对象,承诺实现 DraggableToolbarViewDelegate 的方法也将实现 ToolbarViewDelegate 中的方法。这就是它的意思。



在这种情况下,这意味着 DraggableToolbarView 可以期望其委托来实现 ToolbarViewDelegate 中的方法。


I have a class called ToolbarView which is a subclass of UIView and basically creates a UIView that has a disappearing / reappearing UIToolbar on top. I also have a subclass of ToolbarView called DraggableToolbarView enables the user to drag the view around the screen.

I need to create a delegate for ToolbarView so it can notify another object / class of when the toolbar reappears and disappears. I also need to create a delegate for DraggableToolbarView so I can notify another object / class when the view is dragged. DraggableToolbarViews delegate will also need to notify another object / class of when the toolbar reappears and disappears.

So I decided to implement ToolbarViewDelegate, and have DraggableToolbarViewDelegate inherit from it and have its own method like following:

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

...

When I do this only the DraggableToolbarDelegate methods are responding. However when I also do [drabbleToolbarView setToolbarViewDelegate:self] it works. I've tried doing each delegate separately without inheritence and it works fine so I believe the problem isn't in any other part of the code.

Anyone might know why? I figured by making the protocols inherit, I wouldn't also have to set the ToolbarViewDelegate for a DraggableToolbar object.

UPDATE: Added a lot more code

解决方案

In your code, any given DraggableToolbarView instance has two properties to connect to delegates, one called toolbarViewDelegate which it inherits from its superclass, and one called draggableToolbarViewDelegate which is defined in DraggableToolbarView itself. You've got to set both of those if you want the controller to get all the delegate messages.

What you're trying to do is possible, however. You need to use the same property name in both your view classes, so that there is only one delegate connection for any instance.

First, change the name of the delegate in the superclass. (Note that you don't need, and indeed shouldn't bother, to declare an ivar for the property -- it's created by @synthesize.)

@interface ToolbarView : UIView <UIGestureRecognizerDelegate>
@property (nonatomic, assign) id <ToolbarViewDelegate> delegate;
@end

You will use the same property name in the subclass.

@interface DraggableToolbarView : ToolbarView
@property (nonatomic, assign) id <DraggableToolbarViewDelegate> delegate;
@end

This is allowed as long as the name of the backing ivar in the subclass is different than that of the superclass, e.g.,

// In superclass
@synthesize delegate;
// In subclass
@synthesize delegate = delegate_;

Now change all the delegate messages in the two view classes to use this one property:

- (void)showBars 
{

    if (self.delegate)
    {
        [self.delegate ...

- (void)drag:(UIPanGestureRecognizer *)sender
{
    //...
    if (self.delegate)
    {
        [self.delegate ...

Now you can send setDelegate: to a DraggableToolbarView and it will use the same delegate for the dragging methods and the show/hide methods.

Finally, a terminology/explanatory note. In response to your previous question, Caleb used the correct term for "stacked" protocols, and Richard did not. Protocols don't inherit from each other, but one protocol can adopt the other. The relationship is similar, but distinct. When an object conforms to a protocol, it promises to implement the methods declared in that protocol. No implementation comes along with the protocol. The same is true of one protocol adopting the other -- the methods are just declared to exist in both. When you write:

@protocol DraggableToolbarViewDelegate <ToolbarViewDelegate>

you are saying that any object which promises to implement DraggableToolbarViewDelegate's methods will also implement the methods from ToolbarViewDelegate. That's all that it means. Again, no implementation comes along with that promise.

In this case, that means that a DraggableToolbarView can expect its delegate to implement the methods in ToolbarViewDelegate.

这篇关于尝试实现委托继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆