6

UIView のサブクラスである ToolbarView というクラスがあり、基本的に、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];
        }

        ...
}

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 を設定する必要もなくなると考えました。

更新:さらに多くのコードを追加

4

2 に答える 2

7

コードでは、特定のDraggableToolbarViewインスタンスには、デリゲートに接続するための 2 つのtoolbarViewDelegateプロパティがあります。1つはスーパークラスから継承されて呼び出され、もう 1 つはそれ自体draggableToolbarViewDelegateで定義されて呼び出されDraggableToolbarViewます。コントローラーにすべてのデリゲート メッセージを取得させたい場合は、両方を設定する必要があります。

ただし、あなたがやろうとしていることは可能です。どのインスタンスに対してもデリゲート接続が 1 つだけになるように、両方のビュー クラスで同じプロパティ名を使用する必要があります。

まず、スーパークラスのデリゲートの名前を変更します。(プロパティの 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_;

2 つのビュー クラスのすべてのデリゲート メッセージを、この 1 つのプロパティを使用するように変更します。

- (void)showBars 
{

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

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

に送信できるsetDelegate:ようにDraggableToolbarViewなり、ドラッグ メソッドと表示/非表示メソッドに同じデリゲートが使用されます。

最後に、用語/説明メモです。あなたの以前の質問に答えて、Caleb は「スタックされた」プロトコルの正しい用語を使用しましたが、Richard は使用しませんでした。プロトコルは互いに継承しませんが、一方のプロトコルが他方のプロトコルを採用することはできます。関係は似ていますが、異なります。オブジェクトがプロトコルに準拠すると、そのプロトコルで宣言されたメソッドを実装することが約束されます。プロトコルに付随する実装はありません。同じことが、一方のプロトコルが他方のプロトコルを採用する場合にも当てはまります。メソッドは、両方に存在することが宣言されているだけです。あなたが書くとき:

@protocol DraggableToolbarViewDelegate <ToolbarViewDelegate>

DraggableToolbarViewDelegateのメソッドを実装することを約束するオブジェクトは、 のメソッドも実装すると言っていますToolbarViewDelegate。それだけです。繰り返しますが、その約束を伴う実装はありません。

この場合、それは、DraggableToolbarViewそのデリゲートが のメソッドを実装することを期待できることを意味しToolbarViewDelegateます。

于 2012-05-27T21:54:09.813 に答える
1

あなたはコード全体を提供していませんが、ここにあるものから、

  1. ToolBarView とそのサブクラスにはid <ToolBarViewDelegate>、プロパティとしてデリゲートがあります。
  2. DraggableToolbarViewDelegate は NSObject プロトコルを拡張します。
  3. 他のViewControllerオブジェクトは、ツールバービューではなくデリゲートプロトコルに準拠しています。
  4. コントローラーがデリゲート メソッドの実装を提供し、プロトコルに準拠したら、ビューのオブジェクトのデリゲートを自分自身に設定し、ビューに設定されたデリゲート プロパティを使用してこれらのプロトコル メソッドを呼び出します。
于 2012-05-26T19:09:47.077 に答える