Desencadenar un método en UIViewController desde su vista

Tengo un UIViewController con su UIView que contiene un UIButton . Quiero activar un método en UIViewController onclick en el evento.
Mantener la reference de UIViewController no parece ser una buena idea, como dice el siguiente enlace: ¿ Llegar a UIViewController desde UIView?

Entonces quiero lograr esto usando un delegado. ¿Alguna pista sobre cómo lograr esto?

Puedes hacer algo como esto

CustomView.h

 #import <UIKit/UIKit.h> @protocol CustomViewDelegate <NSObject> -(void)didButtonPressed; @end @interface CustomView : UIView @property (assign) id<CustomViewDelegate> delegate; @end 

CustomView.m

 #import "CustomView.h" @implementation CustomView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code self.backgroundColor = [UIColor whiteColor]; //[self addSubview:titleLbl]; UIButton *button= [UIButton buttonWithType:UIButtonTypeRoundedRect]; button.frame = CGRectMake(100, 100, 100, 50); [button addTarget:self.delegate action:@selector(didButtonPressed) forControlEvents:UIControlEventTouchUpInside]; [button setTitle:@"pressMe" forState:UIControlStateNormal]; [self addSubview:button]; } return self; } 

en su ViewController.m

 -(void)loadView { [super loadView]; CustomView *view = [[CustomView alloc]initWithFrame:self.view.bounds]; view.delegate = self; [self.view addSubview:view]; } 

Supongo que esperabas algo más fundamental y luego pasas un button de acción al controller. Siempre sigo el patrón MVC en caso de queueboración model / vista / controller. Resuelve su problema y muchos otros. Y quiero compartir mi experiencia.

  1. Controlador separado de vista y model: no ponga toda la "lógica de negocios" en classs relacionadas con la vista; Esto hace que el código sea muy inutilizable. Cree classs de controller para alojar este código, pero asegúrese de que las classs de controller no hagan demasiadas suposiciones sobre la presentación.
  2. Defina las API de callback con @protocol , utilizando @optional si no se requieren todos los methods.
  3. Para ver define el protocolo como <view class name>Protocol (ejemplo NewsViewProtocol). Para el controller definir delegado como <view class name>Delegate (ejemplo NewsViewDelegate) y dataSource como <view class name>DataSource (ejemplo NewsViewDataSource). Guarde todos estos @protocols en un file separado llamado <view class name>Protocol.h (ejemplo NewsViewProtocol.h)

Breve ejemplo:

Contenido de NewsView.h

 // // NewsView.h @interface NewsView : UIView <NewsViewProtocol> { @protected NSObject* delegate_; NSObject* dataSource_; } @end 

Contenido de NewsController.h y .m

 // // NewsController.h @interface NewsController : UIViewController <NewsViewDataSource, NewsViewDelegate> { } @property (nonatomic, weak) UIView<NewsViewProtocol>* customView; @end @implementation NewsController - (void)viewDidLoad { [super viewDidLoad]; self.customView = (UIView<NewsViewProtocol>*)self.view; [self.customView setDelegate:self]; [self.customView setDataSource:self]; } @end 

Contenido de NewsViewProtocol.h

 // // NewsViewProtocol.h @protocol NewsViewProtocol; @protocol NewsViewDelegate<NSObject> @optional - (void)someAction; - (void)newsView:(UIView<NewsViewProtocol>*)newsView didSelectItemAtIndexPath:(NSIndexPath *)indexPath; @end @protocol NewsViewDataSource<NSObject> @requinetworking - (id)newsView:(UIView<NewsViewProtocol>*)newsView itemAtIndexPath:(NSIndexPath *)indexPath; - (NSInteger)numberOfItemsInNewsView:(UIView<NewsViewProtocol>*)newsView section:(NSInteger)section; - (BOOL)newsView:(UIView<NewsViewProtocol>*)newsView shouldDisplaySection:(NSInteger)section; @end @protocol NewsViewProtocol<NSObject> @requinetworking //Never retain delegate instance into implementation of this method - (void)setDelegate:(NSObject<NewsViewDelegate>*)delegate; //Never retain delegate instance into implementation of this method - (void)setDataSource:(NSObject<NewsViewDataSource>*)dataSource; - (void)reload; @end 

Puede considerar que es networkingundante. En el controller de vista simple, SÍ. Pero si desarrolla una pantalla muy compleja con una gran cantidad de datos, entonces le ofrece algunas ventajas como:

  • Le ayuda a separar la responsabilidad entre la vista y el controller.
  • Mantiene su código claro.
  • Hace que el código sea más reutilizable.

Esto es para lo que se construyó la cadena de respuesta. Cuando agrega un objective a su button, simplemente suministre nil para el objective:

 [mySpecialButton addTarget:nil action:@selector(mySpecialButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; 

El objective nil básicamente significa "enviar mySpecialButtonTapped: a cualquier object en la cadena de respuesta que pueda manejarlo".

Ahora puede manejar este selector en cualquier parte de la cadena de respuesta, que incluye el button en sí, su vista que contiene, su controller de vista, la aplicación UIA y finalmente su AppDelegate. Simplemente coloque este método en el object más apropiado para sus necesidades:

 - (void)mySpecialButtonTapped:(id)sender { NSLog("My special button was tapped!"); } 

No necesita delegates o bloques de callback (como en la respuesta aceptada) si solo desea hacer upload un post de forma burbuja.

La vida es fácil en xCode.

Al principio, asegúrese de que su Vista xib (la que tiene su button dentro de él) está asociada a la class ViewController correcta. Cuál puede ser la class ViewController pnetworkingeterminada que viene con un nuevo proyecto o uno personalizado.

¡Después de esto, aquí viene el truco de magia! Separe su vista en el panel 2. El objective es ver su xib y su código viewController (el file .m). Ahora presione la tecla de control de su keyboard y arrastre el button UIB al código. Seleccione IBAction. Generará algo que puede llamar un "oyente" en otro idioma. ¡Vaya al código central de su Controlador de vista y complete el método!

¡Fácil como eso! Que te diviertas 🙂

Realmente no necesita delegates para esto, así es como se pretende utilizar UIButtons. Simplemente controle y haga clic y arrastre desde su button al file .m para su UIViewController. Esto creará un nuevo método. A partir de ahí, puede hacer una llamada al método que escribió o simplemente copyr y pegar lo que tiene en el nuevo método.

Puedes probar esto:

 [yourButton addTarget:self action:@selector(yourButtonAction:) forControlEvents:UIControlEventTouchUpInside]; 

Y en su selector especifique la acción

 - (IBAction)yourButtonAction:(id)sender { //Action to perform } 

Para agregar un button mediante progtwigción, en myViewController.m

 UIView *yourView = [[UIView alloc] init]; UIButton *yourButton = [[UIButton alloc] initWithFrame:CGRectMake(0,0,100,21)]; [yourButton addTarget:self action:@selector(yourMethod) forControlEvents:UIControlEventTouchDown]; [yourView addSubview:yourButton]; 

Más información aquí .