ios objective-c iphone delegates

ios - ¿Cómo configuro un delegado simple para comunicarme entre dos controladores de vista?



objective-c iphone (4)

Ejemplo simple ...

Digamos que el controlador de vista infantil tiene un UISlider y queremos pasar el valor del control deslizante a los padres a través de un delegado.

En el archivo de encabezado del controlador de vista secundaria, declare el tipo de delegado y sus métodos:

ChildViewController.h

#import <UIKit/UIKit.h> // 1. Forward declaration of ChildViewControllerDelegate - this just declares // that a ChildViewControllerDelegate type exists so that we can use it // later. @protocol ChildViewControllerDelegate; // 2. Declaration of the view controller class, as usual @interface ChildViewController : UIViewController // Delegate properties should always be weak references // See http://stackoverflow.com/a/4796131/263871 for the rationale // (Tip: If you''re not using ARC, use `assign` instead of `weak`) @property (nonatomic, weak) id<ChildViewControllerDelegate> delegate; // A simple IBAction method that I''ll associate with a close button in // the UI. We''ll call the delegate''s childViewController:didChooseValue: // method inside this handler. - (IBAction)handleCloseButton:(id)sender; @end // 3. Definition of the delegate''s interface @protocol ChildViewControllerDelegate <NSObject> - (void)childViewController:(ChildViewController*)viewController didChooseValue:(CGFloat)value; @end

En la implementación del controlador de vista infantil, llame a los métodos de delegado según sea necesario.

ChildViewController.m

#import "ChildViewController.h" @implementation ChildViewController - (void)handleCloseButton:(id)sender { // Xcode will complain if we access a weak property more than // once here, since it could in theory be nilled between accesses // leading to unpredictable results. So we''ll start by taking // a local, strong reference to the delegate. id<ChildViewControllerDelegate> strongDelegate = self.delegate; // Our delegate method is optional, so we should // check that the delegate implements it if ([strongDelegate respondsToSelector:@selector(childViewController:didChooseValue:)]) { [strongDelegate childViewController:self didChooseValue:self.slider.value]; } } @end

En el archivo de encabezado del controlador de vista principal, declare que implementa el protocolo ChildViewControllerDelegate .

RootViewController.h

#import <UIKit/UIKit.h> #import "ChildViewController.h" @interface RootViewController : UITableViewController <ChildViewControllerDelegate> @end

En la implementación del controlador de vista principal, implemente los métodos de delegado de forma adecuada.

RootViewController.m

#import "RootViewController.h" @implementation RootViewController - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { ChildViewController *detailViewController = [[ChildViewController alloc] init]; // Assign self as the delegate for the child view controller detailViewController.delegate = self; [self.navigationController pushViewController:detailViewController animated:YES]; } // Implement the delegate methods for ChildViewControllerDelegate - (void)childViewController:(ChildViewController *)viewController didChooseValue:(CGFloat)value { // Do something with value... // ...then dismiss the child view controller [self.navigationController popViewControllerAnimated:YES]; } @end

¡Espero que esto ayude!

Tengo dos UITableViewControllers y necesito pasar el valor del controlador de vista hijo al padre utilizando un delegado. Sé lo que son los delegados y solo quería ver un ejemplo simple de seguir.

Gracias


Este código a continuación solo muestra el uso básico del concepto de delegado ... nombre la variable y la clase según su requerimiento.

Primero necesitas declarar un protocolo:

Vamos a llamarlo MyFirstControllerDelegate.h

@protocol MyFirstControllerDelegate - (void) FunctionOne: (MyDataOne*) dataOne; - (void) FunctionTwo: (MyDatatwo*) dataTwo; @end

Importe el archivo MyFirstControllerDelegate.h y confirme su FirstController con el protocolo MyFirstControllerDelegate

#import "MyFirstControllerDelegate.h" @interface FirstController : UIViewController<MyFirstControllerDelegate> { } @end

En el archivo de implementación, debe implementar ambas funciones de protocolo:

@implementation FirstController - (void) FunctionOne: (MyDataOne*) dataOne { //Put your finction code here } - (void) FunctionTwo: (MyDatatwo*) dataTwo { //Put your finction code here } //Call below function from your code -(void) CreateSecondController { SecondController *mySecondController = [SecondController alloc] initWithSomeData:.]; //..... push second controller into navigation stack mySecondController.delegate = self ; [mySecondController release]; } @end

en tu SecondController :

@interface SecondController:<UIViewController> { id <MyFirstControllerDelegate> delegate; } @property (nonatomic,assign) id <MyFirstControllerDelegate> delegate; @end

En el archivo de implementación de SecondController .

@implementation SecondController @synthesize delegate; //Call below two function on self. -(void) SendOneDataToFirstController { [delegate FunctionOne:myDataOne]; } -(void) SendSecondDataToFirstController { [delegate FunctionTwo:myDataSecond]; } @end

Here está el artículo wiki sobre el delegado.


La siguiente solución es un enfoque muy básico y simple para enviar datos de VC2 a VC1 utilizando un delegado.

PD: esta solución está hecha en Xcode 9.X y Swift 4

Declarado un protocolo y creado un delegado var en ViewControllerB

import UIKit //Declare the Protocol into your SecondVC protocol DataDelegate { func sendData(data : String) } class ViewControllerB : UIViewController { //Declare the delegate property in your SecondVC var delegate : DataDelegate? var data : String = "Send data to ViewControllerA." override func viewDidLoad() { super.viewDidLoad() } @IBAction func btnSendDataPushed(_ sender: UIButton) { // Call the delegate method from SecondVC self.delegate?.sendData(data:self.data) dismiss(animated: true, completion: nil) } }

ViewControllerA confirma el protocolo y espera recibir datos a través del método delegado sendData

import UIKit // Conform the DataDelegate protocol in ViewControllerA class ViewControllerA : UIViewController , DataDelegate { @IBOutlet weak var dataLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() } @IBAction func presentToChild(_ sender: UIButton) { let childVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier:"ViewControllerB") as! ViewControllerB //Registered delegate childVC.delegate = self self.present(childVC, animated: true, completion: nil) } // Implement the delegate method in ViewControllerA func sendData(data : String) { if data != "" { self.dataLabel.text = data } } }