¿Cómo puedo crear delegates en Objective-C?

Sé cómo trabajan los delegates, y sé cómo puedo usarlos.

¿Pero cómo los creo?

Un delegado de Objective-C es un object que se ha asignado a la propiedad de delegate otro object. Para crear uno, simplemente defina una class que implemente los methods delegates que le interesan y marque esa class como implementación del protocolo delegado.

Por ejemplo, suponga que tiene una UIWebView . Si desea implementar el método webViewDidStartLoad: de su delegado, puede crear una class como esta:

 @interface MyClass<UIWebViewDelegate> // ... @end @implementation MyClass - (void)webViewDidStartLoad:(UIWebView *)webView { // ... } @end 

Entonces podría crear una instancia de MyClass y asignarla como delegado de la vista web:

 MyClass *instanceOfMyClass = [[MyClass alloc] init]; myWebView.delegate = instanceOfMyClass; 

En el lado de UIWebView , probablemente tenga un código similar a esto para ver si el delegado responde al post webViewDidStartLoad: usando respondsToSelector: y envíelo si corresponde.

 if([self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) { [self.delegate webViewDidStartLoad:self]; } 

La propiedad del delegado en sí misma se declara weak (en ARC) o assign (pre-ARC) para evitar retener loops, ya que el delegado de un object suele tener una fuerte reference a ese object. (Por ejemplo, un controller de vista suele ser el delegado de una vista que contiene.)

Haciendo delegates para tus classs

Para definir sus propios delegates, tendrá que declarar sus methods en algún lugar, como se describe en los Apple Docs sobre protocolos . Por lo general, declaras un protocolo formal. La statement, parafraseada desde UIWebView.h, se vería así:

 @protocol UIWebViewDelegate <NSObject> @optional - (void)webViewDidStartLoad:(UIWebView *)webView; // ... other methods here @end 

Esto es análogo a una interfaz o class base abstracta, ya que crea un tipo especial para su delegado, UIWebViewDelegate en este caso. Los implementadores delegates tendrían que adoptar este protocolo:

 @interface MyClass <UIWebViewDelegate> // ... @end 

Y luego implementa los methods en el protocolo. Para los methods declarados en el protocolo como @optional (como la mayoría de los methods de delegado), debe verificar con -respondsToSelector: antes de llamar a un método particular.

Nombre

Los methods de delegado normalmente se nombran comenzando por el nombre de la class delegante y toman el object delegante como primer parámetro. También usan a menudo una voluntad, un deber o una forma. Entonces, webViewDidStartLoad: (primer parámetro es la vista web) en lugar de loadStarted (sin parameters), por ejemplo.

Optimizaciones de velocidad

En lugar de verificar si un delegado responde a un selector cada vez que queremos enviarlo, puede almacenar en caching esa información cuando se configuran delegates. Una manera muy limpia de hacer esto es usar un bitfield, de la siguiente manera:

 @protocol SomethingDelegate <NSObject> @optional - (void)something:(id)something didFinishLoadingItem:(id)item; - (void)something:(id)something didFailWithError:(NSError *)error; @end @interface Something : NSObject @property (nonatomic, weak) id <SomethingDelegate> delegate; @end @implementation Something { struct { unsigned int didFinishLoadingItem:1; unsigned int didFailWithError:1; } delegateRespondsTo; } @synthesize delegate; - (void)setDelegate:(id <SomethingDelegate>)aDelegate { if (delegate != aDelegate) { delegate = aDelegate; delegateRespondsTo.didFinishLoadingItem = [delegate respondsToSelector:@selector(something:didFinishLoadingItem:)]; delegateRespondsTo.didFailWithError = [delegate respondsToSelector:@selector(something:didFailWithError:)]; } } @end 

Luego, en el cuerpo, podemos verificar que nuestro delegado maneja los posts accediendo a nuestro delegateRespondsTo struct, en lugar de enviar -respondsToSelector: una y otra vez.

Delegados informales

Antes de que existieran los protocolos, era común utilizar una categoría en NSObject para declarar los methods que un delegado podía implementar. Por ejemplo, CALayer sigue CALayer esto:

 @interface NSObject(CALayerDelegate) - (void)displayLayer:(CALayer *)layer; // ... other methods here @end 

Esto esencialmente le dice al comstackdor que cualquier object podría implementar displayLayer:

Luego usaría el mismo -respondsToSelector: como se describió anteriormente para llamar a este método. Los delegates simplemente implementan este método y asignan la propiedad de delegate , y eso es todo (no hay ninguna statement de conformidad con un protocolo). Este método es común en las bibliotecas de Apple, pero el nuevo código debería usar el enfoque de protocolo más moderno arriba, ya que este enfoque contamina NSObject (lo que hace que el autocomplete sea less útil) y dificulta que el comstackdor le avise sobre errores tipocharts y errores similares.

La respuesta aprobada es excelente, pero si está buscando una respuesta de 1 minuto, intente esto:

El file MyClass.h debería verse así (¡agregue líneas delegadas con comentarios!)

 #import <BlaClass/BlaClass.h> @class MyClass; //define class, so protocol can see MyClass @protocol MyClassDelegate <NSObject> //define delegate protocol - (void) myClassDelegateMethod: (MyClass *) sender; //define delegate method to be implemented within another class @end //end protocol @interface MyClass : NSObject { } @property (nonatomic, weak) id <MyClassDelegate> delegate; //define MyClassDelegate as delegate @end 

El file MyClass.m debería verse así

 #import "MyClass.h" @implementation MyClass @synthesize delegate; //synthesise MyClassDelegate delegate - (void) myMethodToDoStuff { [self.delegate myClassDelegateMethod:self]; //this will call the method implemented in your other class } @end 

Para usar su delegado en otra class (UIViewController llamado MyVC en este caso) MyVC.h:

 #import "MyClass.h" @interface MyVC:UIViewController <MyClassDelegate> { //make it a delegate for MyClassDelegate } 

MyVC.m:

 myClass.delegate = self; //set its delegate to self somewhere 

Implementar el método de delegado

 - (void) myClassDelegateMethod: (MyClass *) sender { NSLog(@"Delegates are great!"); } 

Cuando utilizo el método de protocolo formal para crear soporte de delegado, he descubierto que puedes asegurarte de verificar correctamente el tipo (aunque, en time de ejecución, no compile time) agregando algo como:

 if (![delegate conformsToProtocol:@protocol(MyDelegate)]) { [NSException raise:@"MyDelegate Exception" format:@"Parameter does not conform to MyDelegate protocol at line %d", (int)__LINE__]; } 

en su código de acceso delegado (setDelegate). Esto ayuda a minimizar los errores.

¡Por favor! Consulte a continuación un tutorial simple paso a paso para comprender cómo funcionan los delegates en iOS.

Delegado en iOS

He creado dos ViewControllers (para enviar datos de uno a otro)

  1. FirstViewController implementar delegado (que proporciona datos).
  2. SecondViewController declara al delegado (que recibirá los datos).

Tal vez esto es más en la línea de lo que te falta:

Si viene de un punto de vista de C ++, los delegates tardan un poco en acostumbrarse, pero básicamente "simplemente funcionan".

La forma en que funciona es que establece algún object que escribió como el delegado en NSWindow, pero su object solo tiene implementaciones (methods) para uno o algunos de los muchos methods de delegado posibles. Entonces sucede algo y NSWindow quiere llamar a su object; simplemente utiliza el método NSWindow Objective-c para determinar si su object quiere que se llame ese método y luego lo llama. Así es como funciona el objective c: los methods se buscan a demanda.

Es totalmente trivial hacer esto con sus propios objects, no hay nada especial, podría tener, por ejemplo, un NSArray de 27 objects, todos types diferentes de objects, solo 18 de ellos con el método -(void)setToBue; Los otros 9 no. Entonces, para llamar a setToBlue a todos los 18 que lo necesiten, algo como esto:

 for (id anObject in myArray) { if ([anObject respondsToSelector:@selector(@"setToBlue")]) [anObject setToBlue]; } 

La otra cosa sobre los delegates es que no se retienen, por lo que siempre tiene que establecer el delegado a nil en su método MyClass dealloc .

Como una buena práctica recomendada por Apple, es bueno para el delegado (que es un protocolo, por definición), para cumplir con el protocolo NSObject .

 @protocol MyDelegate <NSObject> ... @end 

& para crear methods opcionales dentro de su delegado (es decir, methods que no necesariamente tienen que implementarse), puede usar la anotación @optional como esta:

 @protocol MyDelegate <NSObject> ... ... // Declaration for Methods that 'must' be implemented' ... ... @optional ... // Declaration for Methods that 'need not necessarily' be implemented by the class conforming to your delegate ... @end 

Por lo tanto, cuando use methods que haya especificado como opcionales, debe (en su class) verificar con respondsToSelector si la vista (que se ajusta a su delegado) realmente ha implementado sus methods opcionales o no.

Creo que todas estas respuestas tienen mucho sentido una vez que entiendas a los delegates. Personalmente, vengo de la tierra de C / C ++ y antes de que los lenguajes de procedimiento como Fortran, etc, así que aquí está mi 2 min tomar en encontrar análogos similares en el paradigma C ++.

Si tuviera que explicar a los delegates a un progtwigdor de C ++ / Java, diría

¿Qué son los delegates? Estos son pointers estáticos para las classs dentro de otra class. Una vez que asigna un puntero, puede llamar a funciones / methods en esa class. Por lo tanto, algunas funciones de su class están "delegadas" (en el mundo C ++, puntero por un puntero de object de class) a otra class.

¿Qué son los protocolos? Conceptualmente sirve como propósito similar al file de encabezado de la class que está asignando como class de delegado. Un protocolo es una forma explícita de definir qué methods se deben implementar en la class, cuyo puntero se configuró como un delegado dentro de una class.

¿Cómo puedo hacer algo similar en C ++? Si intentas hacer esto en C ++, definirías pointers a classs (objects) en la definición de class y luego conectándolos a otras classs que proporcionarán funciones adicionales como delegates a tu class base. Pero este cableado debe mantenerse dentro del código y será torpe y propenso a errores. El objective C asume que los progtwigdores no son los mejores en el mantenimiento de este decipline y proporciona restricciones de comstackdor para hacer cumplir una implementación limpia.

Versión Swift

Un delegado es solo una class que funciona para otra class. Lea el siguiente código para un ejemplo de Zona de juegos algo tonta (pero con suerte esclarecedor) que muestra cómo se hace esto en Swift.

 // A protocol is just a list of methods (and/or properties) that must // be used by any class that adopts the protocol. protocol OlderSiblingDelegate: class { // This protocol only defines one requinetworking method func getYourNiceOlderSiblingAGlassOfWater() -> String } class BossyBigBrother { // The delegate is the BossyBigBrother's slave. This position can // be assigned later to whoever is available (and conforms to the // protocol). weak var delegate: OlderSiblingDelegate? func tellSomebodyToGetMeSomeWater() -> String? { // The delegate is optional because there might not be anyone // nearby to boss around. return delegate?.getYourNiceOlderSiblingAGlassOfWater() } } // PoorLittleSister conforms to the OlderSiblingDelegate protocol class PoorLittleSister: OlderSiblingDelegate { // This method is repquinetworking by the protocol, but the protocol said // nothing about how it needs to be implemented. func getYourNiceOlderSiblingAGlassOfWater() -> String { return "Go get it yourself!" } } // initialize the classes let bigBro = BossyBigBrother() let lilSis = PoorLittleSister() // Set the delegate // bigBro could boss around anyone who conforms to the // OlderSiblingDelegate protocol, but since lilSis is here, // she is the unlucky choice. bigBro.delegate = lilSis // Because the delegate is set, there is a class to do bigBro's work for him. // bigBro tells lilSis to get him some water. if let replyFromLilSis = bigBro.tellSomebodyToGetMeSomeWater() { print(replyFromLilSis) // "Go get it yourself!" } 

En la práctica real, los delegates se utilizan a menudo en las siguientes situaciones

  1. Cuando una class necesita comunicar algo de información a otra class
  2. Cuando una class quiere permitir que otra class la personalice

Las classs no necesitan saber nada de antemano, excepto que la class de delegado se ajusta al protocolo requerido.

Le recomiendo leer los siguientes dos artículos. Me ayudaron a entender a los delegates, incluso mejor que la documentation .

  • ¿Qué es la delegación? – Una guía del desarrollador Swift
  • Cómo funciona la delegación: una guía rápida para desarrolladores

Digamos que tiene una class que desarrolló y quiere declarar una propiedad de delegado para poder notificarlo cuando ocurre algún evento:

 @class myClass; @protocol myClassDelegate <NSObject> -(void)myClass:(MyClass*)myObject requinetworkingEventHandlerWithParameter:(ParamType*)param; @optional -(void)myClass:(MyClass*)myObject optionalEventHandlerWithParameter:(ParamType*)param; @end @interface MyClass : NSObject @property(nonatomic,weak)id< MyClassDelegate> delegate; @end 

por lo que declara un protocolo en el file de encabezado MyClass (o un file de encabezado separado) y declara los manejadores de events requeridos / opcionales que su delegado debe / debe implementar, luego declare una propiedad en MyClass de tipo ( id< MyClassDelegate> ), que significa cualquier class objetiva c que se ajuste al protocolo MyClassDelegate , observará que la propiedad de delegado se declara débil, esto es muy importante para evitar el ciclo de retención (la mayoría de las veces el delegado conserva la instancia MyClass , por lo que si declaró que el delegado retiene, ambos de ellos se mantendrán mutuamente y ninguno de ellos será liberado).

notará también que los methods de protocolo pasan la instancia de MyClass al delegado como parámetro, esta es la mejor práctica en caso de que el delegado quiera llamar a algunos methods en la instancia de MyClass y también ayuda cuando el delegado se declara como MyClassDelegate a varias instancias de MyClass , cuando tiene varias instancias UITableView's en su ViewController y se declara como una UITableViewDelegate para todas ellas.

y dentro de su MyClass notifica al delegado con los events declarados de la siguiente manera:

 if([_delegate respondsToSelector:@selector(myClass: requinetworkingEventHandlerWithParameter:)]) { [_delegate myClass:self requinetworkingEventHandlerWithParameter:(ParamType*)param]; } 

primero verifica si su delegado responde al método de protocolo que va a llamar en caso de que el delegado no lo implemente y la aplicación se bloquee (incluso si se requiere el método de protocolo).

Ok, esta no es realmente una respuesta a la pregunta, pero si está buscando cómo hacer su propio delegado, tal vez algo mucho más simple podría ser una mejor respuesta para usted.

Apenas implemento mis delegates porque rara vez lo necesito. Solo puedo tener un delegado para un object delegado. Por lo tanto, si desea que su delegado transmita / transmita datos de forma unidireccional de lo que lo hace con las notifications.

NSNotification puede pasar objects a más de un destinatario y es muy fácil de usar. Funciona así:

El file MyClass.m debería verse así

 #import "MyClass.h" @implementation MyClass - (void) myMethodToDoStuff { //this will post a notification with myClassData (NSArray in this case) in its userInfo dict and self as an object [[NSNotificationCenter defaultCenter] postNotificationName:@"myClassUpdatedData" object:self userInfo:[NSDictionary dictionaryWithObject:selectedLocation[@"myClassData"] forKey:@"myClassData"]]; } @end 

Para usar su notificación en otras classs: Agregar class como observador:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(otherClassUpdatedItsData:) name:@"myClassUpdatedData" object:nil]; 

Implementar el selector:

 - (void) otherClassUpdatedItsData:(NSNotification *)note { NSLog(@"*** Other class updated its data ***"); MyClass *otherClass = [note object]; //the object itself, you can call back any selector if you want NSArray *otherClassData = [note userInfo][@"myClassData"]; //get myClass data object and do whatever you want with it } 

No olvides eliminar tu class como observador si

 - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } 

Aquí hay un método simple para crear delegates.

Crear protocolo en el file .h. Asegúrese de que esté definido antes del protocolo usando @class seguido del nombre del UIViewController < As the protocol I am going to use is UIViewController class>.

Paso: 1: Cree un nuevo Protocolo de class denominado "YourViewController" que será la subclass de la class UIViewController y asigne esta class al segundo ViewController.

Paso: 2: Vaya al file "YourViewController" y modifíquelo de la siguiente manera:

 #import <UIKit/UIkit.h> @class YourViewController; @protocol YourViewController Delegate <NSObject> @optional -(void)defineDelegateMethodName: (YourViewController *) controller; @requinetworking -(BOOL)delegateMethodReturningBool: (YourViewController *) controller; @end @interface YourViewController : UIViewController //Since the property for the protocol could be of any class, then it will be marked as a type of id. @property (nonatomic, weak) id< YourViewController Delegate> delegate; @end 

Los methods definidos en el comportamiento del protocolo pueden controlarse con @optional y @requinetworking como parte de la definición del protocolo.

Paso: 3: Implementación del delegado

  #import "delegate.h" @interface YourDelegateUser () <YourViewControllerDelegate> @end @implementation YourDelegateUser - (void) variousFoo { YourViewController *controller = [[YourViewController alloc] init]; controller.delegate = self; } -(void)defineDelegateMethodName: (YourViewController *) controller { // handle the delegate being called here } -(BOOL)delegateMethodReturningBool: (YourViewController *) controller { // handle the delegate being called here return YES; } @end 

// testing si el método se ha definido antes de llamarlo

  - (void) someMethodToCallDelegate { if ([[self delegate] respondsToSelector:@selector(defineDelegateMethodName:)]) { [self.delegate delegateMethodName:self]; } } 

Para crear su propio delegado, primero debe crear un protocolo y declarar los methods necesarios, sin implementar. Y luego implemente este protocolo en su class de encabezado donde desee implementar los methods delegates o delegates.

Un protocolo debe declararse como a continuación:

 @protocol ServiceResponceDelegate <NSObject> - (void) serviceDidFailWithRequestType:(NSString*)error; - (void) serviceDidFinishedSucessfully:(NSString*)success; @end 

Esta es la class de service donde debe realizarse alguna tarea. Muestra cómo definir el delegado y cómo configurar el delegado. En la class de implementación una vez completada la tarea, se invocan los methods del delegado.

 @interface ServiceClass : NSObject { id <ServiceResponceDelegate> _delegate; } - (void) setDelegate:(id)delegate; - (void) someTask; @end @implementation ServiceClass - (void) setDelegate:(id)delegate { _delegate = delegate; } - (void) someTask { /* perform task */ if (!success) { [_delegate serviceDidFailWithRequestType:@”task failed”]; } else { [_delegate serviceDidFinishedSucessfully:@”task success”]; } } @end 

Esta es la class de vista principal desde donde se llama a la class de service configurando el delegado para sí mismo. Y también el protocolo se implementa en la class de encabezado.

 @interface viewController: UIViewController <ServiceResponceDelegate> { ServiceClass* _service; } - (void) go; @end @implementation viewController // //some methods // - (void) go { _service = [[ServiceClass alloc] init]; [_service setDelegate:self]; [_service someTask]; } 

Eso es todo, y mediante la implementación de methods de delegado en esta class, el control regresará una vez que se realice la operación / tarea.

Descargo de responsabilidad: esta es la versión Swift de cómo crear un delegado.

Entonces, ¿qué son los delegates? … en el desarrollo de software, hay architectures de soluciones reutilizables en general que ayudan a resolver los problemas más comunes dentro de un context dado, estas "templates", por así decirlo, se conocen mejor como patrones de layout. Los delegates son un patrón de layout que permite que un object envíe posts a otro object cuando ocurre un evento específico. Imagine que un object A llama a un object B para realizar una acción. Una vez completada la acción, el object A debe saber que B ha completado la tarea y ha tomado las medidas necesarias, ¡esto puede lograrse con la ayuda de los delegates!

Para una mejor explicación, voy a mostrarle cómo crear un delegado personalizado que pase datos entre classs, con Swift en una aplicación simple, ¡comience por download o clonar este proyecto inicial y ejecutarlo! https://github.com/jamesrochabrun/DelegateTutorial

Puede ver una aplicación con dos classs, ViewController A y ViewController B. B tiene dos vistas que con solo tocar cambian el color de background del ViewController, nada demasiado complicado, ¿verdad? bueno, ahora pensemos de manera fácil también para cambiar el color de background de la class A cuando las vistas de la class B son tocadas.

El problema es que estas vistas son parte de la class B y no tienen idea de la class A, por lo que necesitamos encontrar una forma de comunicarse entre estas dos classs, y ahí es donde brilla la delegación. Dividí la implementación en 6 pasos para que puedas usar esto como una trampa cuando la necesites.

paso 1: busque la marca pragma paso 1 en el file ClassBVC y añada esto

 //MARK: step 1 Add Protocol here. protocol ClassBVCDelegate: class { func changeBackgroundColor(_ color: UIColor?) } 

El primer paso es crear un protocolo, en este caso, vamos a crear el protocolo en la class B, dentro del protocolo puede crear tantas funciones que desee en function de los requisitos de su implementación. En este caso, solo tenemos una function simple que acepta un UIColor opcional como argumento. Es una buena práctica nombrar sus protocolos agregando la palabra delegado al final del nombre de la class, en este caso, ClassBVCDelegate.

paso 2: busque la marca pragma paso 2 en ClassVBC y añada esto

 //MARK: step 2 Create a delegate property here. weak var delegate: ClassBVCDelegate? 

Aquí solo creamos una propiedad delegada para la class, esta propiedad debe adoptar el tipo de protocolo, y debe ser opcional. Además, debe agregar la palabra key débil antes de la propiedad para evitar los ciclos de retención y posibles pérdidas de memory, si no sabe lo que significa que no se preocupe por ahora, recuerde agregar esta palabra key.

paso 3: busque la marca pragma paso 3 dentro del método handleTap en ClassBVC y añada esto

 //MARK: step 3 Add the delegate method call here. delegate?.changeBackgroundColor(tapGesture.view?.backgroundColor) 

Una cosa que debes saber, ejecutar la aplicación y tocar en cualquier vista, no verás ningún comportamiento nuevo y eso es correcto, pero lo que quiero señalar es que la aplicación no se bloquea cuando se llama al delegado, y es porque lo creamos como un valor opcional y es por eso que no se bloqueará, incluso el delegado no existe todavía. Vayamos ahora al file ClassAVC y háganlo, el delegado.

paso 4: busque el paso 4 de la marca pragma dentro del método handleTap en ClassAVC y agregue esto junto al tipo de class como este.

 //MARK: step 4 conform the protocol here. class ClassAVC: UIViewController, ClassBVCDelegate { } 

Ahora, ClassAVC adoptó el protocolo ClassBVCDelegate, puede ver que su comstackdor le está dando un error que dice que "Type" ClassAVC no cumple con el protocolo 'ClassBVCDelegate' y esto solo significa que no utilizó los methods del protocolo, imagínese que cuando la class A adopta el protocolo es como firmar un contrato con la class B y este contrato dice: "¡Cualquier class que me adopte DEBE usar mis funciones!".

Nota rápida: si provienes de un background de Objective-C probablemente estás pensando que también puedes cerrar ese error haciendo que ese método sea opcional, pero para mi sorpresa, y probablemente la tuya, el lenguaje Swift no admite protocolos opcionales, si quieres hazlo puedes crear una extensión para tu protocolo o usar la palabra key @objc en tu implementación de protocolo.

Personalmente, si tengo que crear un protocolo con diferentes methods opcionales, preferiría dividirlo en diferentes protocolos, de esa manera seguiré el concepto de dar una sola responsabilidad a mis objects, pero puede variar según la implementación específica.

aquí hay un buen artículo sobre methods opcionales. https://www.avanderlee.com/swift-2-0/optional-protocol-methods/

paso 5: busca el paso 5 de la marca pragma dentro del método de preparación para segue y añádelo

 //MARK: step 5 create a reference of Class B and bind them through the prepareforsegue method. if let nav = segue.destination as? UINavigationController, let classBVC = nav.topViewController as? ClassBVC { classBVC.delegate = self } 

Aquí solo estamos creando una instancia de ClassBVC y asignamos su delegado a uno mismo, pero ¿qué es yo aquí? ¡Bien, yo soy el ClassAVC que ha sido delegado!

Paso 6: Finalmente, busque el paso 6 del pragma en ClassAVC y usemos las funciones del protocolo, comience a escribir func changeBackgroundColor y verá que lo está completando automáticamente. Puede agregar cualquier implementación dentro de este, en este ejemplo, solo cambiaremos el color de background, agregue esto.

 //MARK: step 6 finally use the method of the contract func changeBackgroundColor(_ color: UIColor?) { view.backgroundColor = color } 

¡Ahora ejecuta la aplicación!

Los delegates están en todas partes y es probable que los use sin previo aviso, si crea una vista de tabla en el pasado que utilizó la delegación, muchas classs de UIKIT funcionan a su alnetworkingedor y muchos otros frameworks también, resuelven estos problemas principales.

  • Evite el acoplamiento apretado de objects.
  • Modifique el comportamiento y la apariencia sin necesidad de subclass de objects.
  • Permitir que las tareas se lleven a cualquier object arbitrario.

Enhorabuena, solo implementas un delegado personalizado, sé que probablemente estás pensando, ¿hay tantos problemas solo por esto? bueno, la delegación es un patrón de layout muy importante para comprender si quieres convertirte en un desarrollador de iOS, y siempre tener en count que tienen una relación de uno a uno entre los objects.

Puede ver el tutorial original aquí https://medium.com/compileswift/implementing-delegates-in-swift-step-by-step-d3211cbac3ef

Delegado: – Crea

 @protocol addToCartDelegate <NSObject> -(void)addToCartAction:(ItemsModel *)itemsModel isAdded:(BOOL)added; @end 

Envía y asigna delegado para ver que estás enviando datos

 [self.delegate addToCartAction:itemsModel isAdded:YES]; 

ViewController.h

 @protocol NameDelegate <NSObject> -(void)delegateMEthod: (ArgType) arg; @end @property id <NameDelegate> delegate; 

ViewController.m

 [self.delegate delegateMEthod: argument]; 

MainViewController.m

 ViewController viewController = [ViewController new]; viewController.delegate = self; 

Método:

 -(void)delegateMEthod: (ArgType) arg{ } 
 //1. //Custom delegate @protocol TB_RemovedUserCellTag <NSObject> -(void)didRemoveCellWithTag:(NSInteger)tag; @end //2. //Create a weak reference in a class where you declanetworking the delegate @property(weak,nonatomic)id <TB_RemovedUserCellTag> removedCellTagDelegate; //3. // use it in the class [self.removedCellTagDelegate didRemoveCellWithTag:self.tag]; //4. import the header file in the class where you want to conform to the protocol @interface MyClassUsesDelegate ()<TB_RemovedUserCellTag> @end 

// 5. Implementar el método en la class .m – (void) didRemoveCellWithTag: label (NSInteger) {NSLog @ ("Etiqueta% d", label);

}

Desde mi punto de vista, crea classs separadas para ese método de delegado y puedes usarlas donde quieras.

en mi Custom DropDownClass.h

 typedef enum { DDSTATE, DDCITY }DropDownType; @protocol DropDownListDelegate <NSObject> @requinetworking - (void)dropDownDidSelectItemWithString:(NSString*)itemString DropDownType:(DropDownType)dropDownType; @end @interface DropDownViewController : UIViewController { BOOL isFiltenetworking; } @property (nonatomic, assign) DropDownType dropDownType; @property (weak) id <DropDownListDelegate> delegate; @property (strong, nonatomic) NSMutableArray *array1DropDown; @property (strong, nonatomic) NSMutableArray *array2DropDown; 

después de que el file in.m cree una matriz con objects,

  - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ CGFloat rowHeight = 44.0f; return rowHeight; } -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return isFiltenetworking?[self.array1DropDown count]:[self.array2DropDown count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *simpleTableIdentifier = @"TableCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier]; } if (self.delegate) { if (self.dropDownType == DDCITY) { cell.textLabel.text = [self.array1DropDown objectAtIndex:indexPath.row]; } else if (self.dropDownType == DDSTATE) { cell.textLabel.text = [self.array2DropDown objectAtIndex:indexPath.row]; } } return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self dismissViewControllerAnimated:YES completion:^{ if(self.delegate){ if(self.dropDownType == DDCITY){ [self.delegate dropDownDidSelectItemWithString:[self.array1DropDown objectAtIndex:indexPath.row] DropDownType:self.dropDownType]; } else if (self.dropDownType == DDSTATE) { [self.delegate dropDownDidSelectItemWithString:[self.array2DropDown objectAtIndex:indexPath.row] DropDownType:self.dropDownType]; } } }]; } 

Here all are set for Custom delegate class.after that you can use this delegate method where you want.for example…

in my another viewcontroller import after that

create action for calling delegate method like this

 - (IBAction)dropDownBtn1Action:(id)sender { DropDownViewController *vehicleModelDropView = [[DropDownViewController alloc]init]; vehicleModelDropView.dropDownType = DDCITY; vehicleModelDropView.delegate = self; [self presentViewController:vehicleModelDropView animated:YES completion:nil]; } 

after that call delegate method like this

 - (void)dropDownDidSelectItemWithString:(NSString *)itemString DropDownType:(DropDownType)dropDownType { switch (dropDownType) { case DDCITY:{ if(itemString.length > 0){ //Here i am printing the selected row [self.dropDownBtn1 setTitle:itemString forState:UIControlStateNormal]; } } break; case DDSTATE: { //Here i am printing the selected row [self.dropDownBtn2 setTitle:itemString forState:UIControlStateNormal]; } default: break; } } 

Let's start with an example , if we buy a product online ,it goes through process like shipping/delivery handled by different teams.So if shipping gets completed ,shipping team should notify delivery team & it should be one to one communication as broadcasting this information would be overhead for other people / vendor might want to pass this information only to requinetworking people.

So if we think in terms of our app, an event can be an online order & different teams can be like multiple views.

Here is code consider ShippingView as Shipping team & DeliveryView as delivery team :

 //Declare the protocol with functions having info which needs to be communicated protocol ShippingDelegate : class { func productShipped(productID : String) } //shippingView which shows shipping status of products class ShippingView : UIView { weak var delegate:ShippingDelegate? var productID : String @IBAction func checkShippingStatus(sender: UIButton) { // if product is shipped delegate?.productShipped(productID: productID) } } //Delivery view which shows delivery status & tracking info class DeliveryView: UIView,ShippingDelegate { func productShipped(productID : String) { // update status on view & perform delivery } } //Main page on app which has both views & shows updated info on product whole status class ProductViewController : UIViewController { var shippingView : ShippingView var deliveryView : DeliveryView override func viewDidLoad() { super.viewDidLoad() // as we want to update shipping info on delivery view, so assign delegate to delivery object // whenever shipping status gets updated it will call productShipped method in DeliveryView & update UI. shippingView.delegate = deliveryView // } } 
    Intereting Posts