motionBegan: No funciona

Me encuentro con un pequeño problema cuando bash usar (vacío) motionBegan: (UIEventSubtype) movimiento con Evento: (UIEvent *) evento para capturar un evento shake. El problema es que la función ni siquiera se está ejecutando, incluso cuando anulo canBecomeFirstResponder y lo configuro para que devuelva SÍ. He visto publicaciones de otras personas con este problema, pero no he encontrado una respuesta.

¡Gracias por cualquier ayuda!

Primer ejemplo .h (clase heredada de UIView – Es “llamada” desde la clase de delegado de la aplicación) {

@class TestApplicationView; @interface TestApplicationView : UIView { IBOutlet UIView *view; } 

}

Primer ejemplo .m {

 - (id)initWithCoder:(NSCoder *)coder { [self setUpView]; return self; } - (id)initWithFrame:(CGRect)frame { [self setUpView]; return self; } - (void)setUpView { [self becomeFirstResponder]; NSLog(@"First Responder - %d", [self isFirstResponder]); } 

}

Segundo ejemplo .h (clase heredada de UIApplicationDelegate y UIScrollViewDelegate) {

 #import  @class TestApplicationViewController; @interface TestApplicationAppDelegate : NSObject  { IBOutlet UIWindow *window; IBOutlet UIScrollView *scrollView; } 

}

Segundo ejemplo .m {

 - (void)applicationDidFinishLaunching:(UIApplication *)application { [self becomeFirstResponder]; } 

}

– El segundo ejemplo devuelve la siguiente advertencia: ‘TestApplicationAppDelegate’ puede no responder a ‘-becomeFirstResponder’

Supongo que desea implementar esto en una subclase de UIViewController . Haga que el UIViewController capaz de convertirse en el primer respondedor:

 - (BOOL)canBecomeFirstResponder { return YES; } 

Haga que UIViewController convierta en el primero en responder en viewDidAppear:

 - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self becomeFirstResponder]; } 

Si la vista contiene algún elemento, como un UITextField , que podría convertirse en el primer respondedor, asegúrese de que ese elemento renuncie a la primera respuesta en algún momento. Con un UITextField , por ejemplo, el UIViewController necesitaría implementar el protocolo UITextFieldDelegate , y en realidad ser el delegado. Luego, en textFieldShouldReturn:

 - (BOOL)textFieldShouldReturn:(UITextField *)theTextField { // Hides the keyboard [theTextField resignFirstResponder]; // Returns first responder status to self so that shake events register here [self becomeFirstResponder]; return YES; } 

Implementar motionEnded:withEvent:

 - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { if ( event.subtype == UIEventSubtypeMotionShake ) { // Do something } if ([super respondsToSelector:@selector(motionEnded:withEvent:)]) { [super motionEnded:motion withEvent:event]; } } 

Hay una buena publicación de Matt Drance de Apple en los foros de desarrolladores de iPhone (requiere registrarse como desarrollador).

Actualización: implementación en una subclase de UIView

Como se discutió en los comentarios, esto también funciona, no demasiado sorprendentemente, en una subclase de UIView . He aquí cómo construir un ejemplo mínimo.

Cree un nuevo proyecto de Aplicación basado en Vista, ShakeTest . Crea una nueva subclase de UIView , UIView ShakeView . Haz que ShakeView.h vea así:

 #import  @interface ShakeView : UIView { } @end 

Haz que ShakeView.m vea así:

 #import "ShakeView.h" @implementation ShakeView - (BOOL)canBecomeFirstResponder { return YES; } - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { if ( event.subtype == UIEventSubtypeMotionShake ) { NSLog(@"Shake!"); } if ([super respondsToSelector:@selector(motionEnded:withEvent:)]) { [super motionEnded:motion withEvent:event]; } } @end 

Haga que ShakeTestViewController.h vea así:

 #import  #include "ShakeView.h" @interface ShakeTestViewController : UIViewController { ShakeView *s; } @end 

Haga que ShakeTestViewController.m vea así:

 #import "ShakeTestViewController.h" @implementation ShakeTestViewController - (void)viewDidLoad { [super viewDidLoad]; s = [[ShakeView alloc] init]; [[self view] addSubview:s]; [s becomeFirstResponder]; } - (void)dealloc { [s release]; [super dealloc]; } @end 

Construir y correr Presiona Cmd-Ctrl-Z para sacudir el simulador de iPhone. Maravíllate con el mensaje de registro.

¿Tienes implementado el antiguo método? Si tiene implementado el antiguo método de aplicación amplia, debe eliminarlo antes de que se llame al nuevo.