2010-06-15 20 views
5

Probé muchas cosas, todavía no se obtuvieron resultados.UIButton addTarget: action: forControlEvents: resultados en [NSObject doesNotRecognizeSelector:]

así que tengo el siguiente botón creado mediante programación en una subclase de UIViewController:

rightButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
    rightButton.frame = CGRectMake(0.0, 0.0, 110.0, 40.0); 
    rightButton.titleLabel.font = [UIFont fontWithName:GAME_FONT_NAME_STRING size:20.0]; 
    [rightButton setTitle:@"MyTitle" forState:UIControlStateNormal]; 
    rightButton.backgroundColor = [UIColor clearColor]; 
    [rightButton setTitleColor:[UIColor greenColor] forState:UIControlStateNormal]; 
    [rightButton setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted]; 
    [rightButton setBackgroundImage:normalImage forState:UIControlStateNormal]; 
    [rightButton setBackgroundImage:highlightedImage forState:UIControlStateHighlighted]; 
    [rightButton addTarget:self action:@selector(myButton) forControlEvents:UIControlEventTouchUpInside]; 
    [self.view addSubview:rightButton]; 

donde el selector es:

- (void)myButton; 

He intentado todo:

- (void)myButton; 
- (void)myButton:(id)sender; 
- (void)myButton:(id)sender forEvent:(UIEvent *)event; 
- (IBAction)myButton; 
- (IBAction)myButton:(id)sender; 
- (IBAction)myButton:(id)sender forEvent:(UIEvent *)event; 

y la selectores correspondientes, por supuesto:

[rightButton addTarget:self action:@selector(myButton) forControlEvents:UIControlEventTouchUpInside]; 
[rightButton addTarget:self action:@selector(myButton:) forControlEvents:UIControlEventTouchUpInside]; 
[rightButton addTarget:self action:@selector(myButton:forEvent:) forControlEvents:UIControlEventTouchUpInside]; 
[rightButton addTarget:self action:@selector(myButton) forControlEvents:UIControlEventTouchUpInside]; 
[rightButton addTarget:self action:@selector(myButton:) forControlEvents:UIControlEventTouchUpInside]; 
[rightButton addTarget:self action:@selector(myButton:forEvent:) forControlEvents:UIControlEventTouchUpInside]; 

El resultado es siempre una excepción no detectada - [NSObject doesNotRecognizeSelector:]. Sin embargo, la traza inversa habitual del programa es:

#0 0x92a6bedb in objc_msgSend() 
#1 0x03b0a430 in ??() 
#2 0x00306b4e in -[UIControl sendAction:to:forEvent:]() 
#3 0x00308d6f in -[UIControl(Internal) _sendActionsForEvents:withEvent:]() 
#4 0x00307abb in -[UIControl touchesEnded:withEvent:]() 
#5 0x002bcddf in -[UIWindow _sendTouchesForEvent:]() 
#6 0x002a67c8 in -[UIApplication sendEvent:]() 
#7 0x002ad061 in _UIApplicationHandleEvent() 
#8 0x02498d59 in PurpleEventCallback() 
#9 0x01cabb80 in CFRunLoopRunSpecific() 
#10 0x01caac48 in CFRunLoopRunInMode() 
#11 0x02497615 in GSEventRunModal() 
#12 0x024976da in GSEventRun() 
#13 0x002adfaf in UIApplicationMain() 

¿Cuál es el problema con ese botón?

PD: estoy usando el iPhone SDK 3.1.3


actualización!

El código siguiente en el AppDelegate (no hay declaraciones en la interfaz):

- (void)applicationDidFinishLaunching:(UIApplication *)application { 
    UIButton *test = [[UIButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 100.0)]; 
    [test setTitle:@"Title" forState:UIControlStateNormal]; 
    UIImage *bg = [UIImage imageNamed:...]; 
    [test setBackgroundImage:bg forState:UIControlStateNormal]; 
    [test addTarget:self action:@selector(testAction) forControlEvents:UIControlEventTouchUpInside]; 
    [window addSubview:test]; 
    [test release]; 
    [window makeKeyAndVisible]; 
} 

- (void)testAction { 
    NSLog(@"Write something..."); 
} 

funciona perfectamente!

Pero si creo una UIViewController vacío con el mismo código:

- (void)viewDidLoad { 
    UIButton *test = [[UIButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 100.0)]; 
    [test setTitle:@"Title" forState:UIControlStateNormal]; 
    UIImage *bg = [UIImage imageNamed:...]; 
    [test setBackgroundImage:bg forState:UIControlStateNormal]; 
    [test addTarget:self action:@selector(testAction) forControlEvents:UIControlEventTouchUpInside]; 
    [self.view addSubview:test]; 
    [test release]; 
    [window makeKeyAndVisible]; 
} 

- (void)testAction { 
    NSLog(@"Write something..."); 
} 

me sale este misterioso error. :-(Ayuda

Respuesta

8

¡LA SOLUCIÓN!

Mi problema era que yo utilicé el código siguiente en el AppDelegate:

UIViewController *controller = [[MyCustomController alloc] init]; 
[window addSubview:controller.view]; 
[controller release]; 

Por lo que sólo se conservó la ventana de propiedades del controlador de vista y todo lo demás fue purgado. El controlador de vista no tenía ninguna funcionalidad (sin eventos táctiles, sin métodos de instancia). Es por eso que addTarget: action: forEvents: no funcionó.

Por lo tanto, hazlo de forma inteligente: libera tus controladores de vista en el trámite de la AppDelegate.;)

+0

Después de que se ha introducido ARC, la solución es ligeramente diferente. Ahora necesita declarar el controlador UIViewController * en el archivo de encabezado. Entonces es una variable miembro de la clase y se retuvo internamente. Simplemente no llame a la versión porque usa ARC como usted sabe. –

0

donde está myButton ser declarado si se sintetiza, a continuación, en lugar de

rightButton = [UIButton buttonWithType: UIButtonTypeCustom];!?

uso

self.rightButton = [UIButton buttonWithType:UIButtonTypeCustom]; 

que debería funcionar. De lo contrario, publique cómo está declarando la propiedad

+0

No creo que esta es la cuestión aquí. Este controlador de vista crea su vista programáticamente (sin ningún archivo xib). El botón es solo una variable de instancia (no una propiedad) en la clase, entonces: self.rightButton = ... no compila en absoluto. Incluso creé un botón directamente en el código. UIButton * button2 = [UIBulton buttonWithType: UIButtonTypeCustom]; ... [self.view addSubview: button2]; Cuando no agrego un objetivo y una acción, los botones se procesan y actúan normalmente. Cuando agrego la funcionalidad (addTarget: action: forEvents :) la excepción se produce con un clic. – Teodor

31

una entrada antigua y probablemente todas clasificado por ahora, pero hay otro problema que va a causar un accidente:

[test addTarget:self action:@selector(testAction) forControlEvents:UIControlEventTouchUpInside] 

es incorrecto. action:@selector(testAction) debe tener dos puntos hay por lo tanto:

action:@selector(testAction:) 

o de lo contrario obtendrá un accidente de selección no reconocido - que es lo que está recibiendo ..

+1

Desearía poder haberte votado +100 por esto, me has ahorrado horas de arañazo. Si omite los dos puntos, establecer un destino selector sin Id funciona, pero no sirve de mucho. Agregar el colon realiza la magia. Pocas veces he visto código tan oscuro y se ha perdido fácilmente – Cruachan

+1

Sí --- acabo de enterarme de esto --- que el colon es crítico --- gracias a Dios skajam66 escribe esta respuesta. – David

+0

Tuve el mismo problema. Gracias por señalar esto! –