2011-04-25 9 views
11

He creado una subclase de UIView y me gustaría que publique eventos personalizados que se muestran en Interface Builder (en realidad Xcode4) del mismo La forma en que los controles como UIButton tienen un montón de eventos en el área "Eventos enviados" cuando haces clic derecho en un control en el diseñador de Xcode 4. Sé que puedo usar la Delegación (a través de Protocolos) o la Notificación (a través del UINotificationCenter) para permitir que los objetos que utilizan mi vista personalizada sepan cuándo ocurren ciertas cosas, pero me gustaría saber si el "Mecanismo de acción del objetivo" (descrito en Cocoa Fundamentals Guide) es apropiado/deseable/posible de usar e integrar con el diseñador de Xcode. Procedente de un fondo principalmente .NET, este enfoque parece estar estrechamente relacionado con el modelo de eventos .NET y tiene más sentido para mí.Agregar mi propio evento a "Eventos enviados" en el menú del Interface Builder para mi UIView personalizado

Respuesta

5

Hay UIControlEventApplicationReserved, que le ofrece una gama de identificadores de eventos que su aplicación puede usar. Sin embargo, no creo que haya ninguna forma de decirle a Interface Builder acerca de los eventos definidos por la aplicación, por lo que no obtendrás el mismo soporte para tus eventos en IB como lo haces para los eventos estándar de UIControl. En cambio, deberá especificar el objetivo y la acción para cada evento definido en la aplicación en el código. (Por favor, alguien me corrige si me equivoco en este punto.) Eso no es para nada difícil, pero es un poco diferente.

+0

Ah, OK. Tener que proporcionar el "objetivo" parece mucho más desordenado que simplemente configurar un delegado, aunque supongo que podría hacer que mi UIView personalizado lo tomara (a través de una propiedad o método) como un NSObject para que mi vista no tuviera que incluir encabezados. para objetos que se encuentran más arriba en la jerarquía de aplicaciones y que están estrechamente relacionados. Mi suposición es que esto es lo que sucede al hacer una conexión en el diseñador, por lo que es probablemente lo mismo. Parece que el método estándar o quizás preferible es simplemente usar Delegación. No pude encontrar mucha información sobre el "Mecanismo de acción objetivo" antes mencionado. – dreyln

+0

Son ideas muy similares. Un controlador de vista suele ser el objetivo y/o delegado de las vistas y controles que administra. En ese caso, simplemente pasaría 'self' como el objetivo y uno de sus selectores como la acción en una llamada a '-addTarget: action: forControlEvents:'. – Caleb

3

Una forma simple de hacerlo es ampliar UIControl en lugar de UIView, esto le permitirá agregar un objetivo a todos los eventos predeterminados (igual que UIButton, etc.).

Nota: para que mi UIControl personalizado maneje los eventos en lugar de los controles que superé en capas, tuve que asegurarme de que userInteractionEnabled = NO se estableciera en todos los controles en capas.

1

Puede hacerlo utilizando una IBOutletCollection. La ventaja de este enfoque es que puede vincular objetos en Interface Builder. El inconveniente es que no puede vincular directamente a IBActions (como UIControl). Aquí es una aplicación limpia utilizando un protocolo:

ObserverProtocol.h

@protocol ObserverProtocol <NSObject> 
- (void)observedObjectChanged:(id)sender; 
@end 

MyObject.h

@interface MyObject : NSObject 
{ 
@private 
    IBOutletCollection(id<ObserverProtocol>) NSArray *observers; 
} 
- (void)objectChanged; 

MyObject.m

@implementation MyObject 

- (void)objectChanged 
{ 
    for (id<ObserverProtocol> observer in observers) 
    { 
     if ([observer respondsToSelector:@selector(observedObjectChanged:)]) 
     { 
      [observer observedObjectChanged:self]; 
     } 
    } 
} 

@end 

Entonces sólo tiene que poner en práctica ObserverProtocol en las clases que desea observar el evento (y para hacer el enlace en Interface Builder, por supuesto).

Cuestiones relacionadas