2012-05-26 16 views
5

Tengo una clase llamada ToolbarView que es una subclase de UIView y básicamente crea una UIView que tiene una UIToolbar que desaparece/reaparece en la parte superior. También tengo una subclase de ToolbarView llamada DraggableToolbarView que permite al usuario arrastrar la vista por la pantalla.Intentando Implementar Herencia de Delegados

Necesito crear un delegado para ToolbarView para que pueda notificar a otro objeto/clase de cuando la barra de herramientas vuelve a aparecer y desaparece. También necesito crear un delegado para DraggableToolbarView para poder notificar a otro objeto/clase cuando se arrastra la vista. El delegado DraggableToolbarViews también deberá notificar a otro objeto/clase cuando la barra de herramientas vuelva a aparecer y desaparezca.

así que decidí poner en práctica ToolbarViewDelegate, y han DraggableToolbarViewDelegate heredar de ella y tener su propio método como el siguiente:

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

     ... 
} 

Toolb arViewDelegate.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]; 

... 

Cuando hago esto sólo los métodos DraggableToolbarDelegate están respondiendo. Sin embargo, cuando también hago [drabbleToolbarView setToolbarViewDelegate:self], funciona. He intentado hacer cada delegado por separado sin herencia y funciona bien, así que creo que el problema no está en ninguna otra parte del código.

¿Alguien podría saber por qué? Pensé que al hacer que los protocolos heredasen, no tendría que configurar ToolbarViewDelegate para un objeto DraggableToolbar.

ACTUALIZACIÓN: Se ha añadido un código mucho más

Respuesta

6

En su código, cualquier dado DraggableToolbarView instancia tiene dos propiedades de conectarse a los delegados, uno llamado toolbarViewDelegate que hereda de su superclase, y uno llamado draggableToolbarViewDelegate que se define en DraggableToolbarView sí. Debe establecer ambos si desea que el controlador obtenga todos los mensajes de delegado.

Lo que estás tratando de hacer es posible, sin embargo. Debe usar el mismo nombre de propiedad en ambas clases de vista, de modo que solo haya una conexión de delegado para cualquier instancia.

Primero, cambie el nombre del delegado en la superclase. (Tenga en cuenta que no es necesario, y de hecho no debe molestarse, para declarar una Ivar para la propiedad - es creado por @synthesize.)

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

que va a utilizar el mismo nombre de la propiedad en la subclase.

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

Esto está permitido siempre que el nombre de la Ivar respaldo en la subclase es diferente que la de la superclase, por ejemplo,

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

Ahora cambiar todos los mensajes de delegado en las dos clases de vista para utilizar esta una propiedad:

- (void)showBars 
{ 

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

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

Ahora usted puede enviar a un setDelegate:DraggableToolbarView y utilizará el mismo delegado para los métodos de arrastre y el espectáculo/hI de métodos.

Finalmente, una terminología/nota explicativa. En respuesta a your previous question, Caleb usó el término correcto para protocolos "apilados", y Richard no. Los protocolos no heredan entre sí, pero un protocolo puede adoptar el otro. La relación es similar, pero distinta. Cuando un objeto cumple con un protocolo, se compromete a implementar los métodos declarados en ese protocolo. Ninguna implementación viene junto con el protocolo. Lo mismo puede decirse de un protocolo que adopta el otro: los métodos se acaban de declarar que existen en ambos.Cuando se escribe:

@protocol DraggableToolbarViewDelegate <ToolbarViewDelegate> 

que está diciendo que cualquier objeto que promete implementar métodos DraggableToolbarViewDelegate 's también implementará los métodos de ToolbarViewDelegate. Eso es todo lo que significa. Nuevamente, ninguna implementación viene junto con esa promesa.

En este caso, eso significa que un DraggableToolbarView puede esperar que su delegado implemente los métodos en ToolbarViewDelegate.

+0

Apreciar esa excelente publicación. Creo que podría limitarme a mantener a los delegados separados, no un gran admirador de los nombres. ¿Qué harías o recomendarías hacer normalmente? –

+0

Me alegro de poder ayudar. No veo nada malo al anular la propiedad delegada; hace que ambos lados del código estén más limpios. –

1

usted no ha dado el código completo, sino de todo lo que es aquí, Asegúrese de que

  1. Su ToolBarView y sus subclases tienen un delegado id <ToolBarViewDelegate> como una propiedad.
  2. Su DraggableToolbarViewDelegate extiende el protocolo NSObject.
  3. y su otro objeto ViewController se ajusta al protocolo de delegado y no a la barra de herramientas.
  4. Una vez que su controlador da implementación de métodos de delegados y se ajusta al protocolo, establezca el objeto del delegado de vista a sí mismo y luego use la propiedad delegar establecida en la vista para llamar a estos métodos de protocolo.