El delegado de UIView personalizado no detecta toquesBegan

Hice mi investigación pero no encontré una respuesta al siguiente problema: tengo un delegado personalizado -subclass de UIView- y, por alguna razón, toquesBegan no funciona en la implementación de delegates.

TestView.h

#import <UIKit/UIKit.h> @class TestView; @protocol TestViewDelegate <NSObject> @end @interface TestView : UIView @property (assign) id <TestViewDelegate> delegate; @end 

TestView.m

 #import "TestView.h" @implementation TestView @synthesize delegate = _delegate; - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"Touch detected on TestViewDelegate"); } @end 

ViewController.h

 #import <UIKit/UIKit.h> #import "TestView.h" @interface ViewController : UIViewController<TestViewDelegate> @end 

ViewController.m

 #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UILabel* title = [[UILabel alloc] initWithFrame:CGRectMake(20, 30, 280, 40)]; [title setFont:[UIFont fontWithName:@"Helvetica-Bold" size:30]]; [title setTextColor:[UIColor blackColor]]; [title setTextAlignment:UITextAlignmentCenter]; [title setBackgroundColor:[UIColor clearColor]]; [tile setText:@"Test"]; [self.view addSubview:title]; } - (void)viewDidUnload { [super viewDidUnload]; } @end 

¿Qué me falta para asegurarse de que touchesBegan de TestView.m se llama cuando se producen toques en ViewController.m?

Su última línea indica un malentendido fundamental de vistas y controlleres de vista. Los toques no ocurren en los controlleres de vista; los toques se producen en las vistas. Después de tocar una vista, le dice a su controller que se tocó, y el controller hace algo con esta información. La forma en que lo hace es a través de un patrón llamado delegación.

Así que repasemos esta pieza por pieza. Para get lo que deseas, tendrías que hacer lo siguiente:

Primero: cree una instancia de TestView y agréguela como una subvista de la vista del controller de vista.

Ahora la vista existe, y cuando la tocas verás tu "Touch detected on TestViewDelegate" conectado a la console. Pero en realidad no hará nada con el delegado (¡ni siquiera hay un delegado todavía!).

Segundo: establezca la propiedad delegate TestView recién creada en el controller de vista. Haga esto después de crear la instancia de TestView pero antes de agregarla a la jerarquía de la vista.

Ahora están conectados un poco, pero la vista nunca está hablando con su delegado (esto no ocurre automáticamente; cuando crea un protocolo de delegado, debe especificar qué posts la vista podrá enviar).

Tercero: agregue un método al protocolo TestViewDelegate e implemente ese método en el controller de vista. Esto podría ser algo así como el touchesBeganOnTestView:(TestView *)sender , o cualquier otra cosa que desee que la vista le diga al delegado cuando se toca. Eso se parece a esto:

 @class TestView; @protocol TestViewDelegate <NSObject> - (void)touchesBeganOnTestView:(TestView *)sender; @end 

@class agregar la línea @class porque la statement de protocolo viene antes de la statement de TestView : en ese punto del file, el comstackdor no sabe lo que significa " TestView ", por lo que para evitar una advertencia, diga "no" Preocupe, lo declararé más tarde ".

Cuarto: invoque ese método desde los touchesBegan de TestView . Esto es tan simple como agregar la línea [self.delegate touchesBeganOnTestView:self]; .

Eso te dará lo que quieras. A partir de su pregunta, reconozco que eres bastante nuevo en iOS / Objective-C, y será difícil si no tienes una sólida comprensión de los fundamentos. Un buen lugar para comenzar podría ser la descripción de la delegación de Apple .