¿Cómo creo delegados en Objective-C?

votos
683

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

¿Pero cómo los creo?

Publicado el 09/03/2009 a las 17:06
fuente por usuario
En otros idiomas...                            


19 respuestas

votos
852

Un delegado de Objective-C es un objeto que ha sido asignado a la delegatepropiedad de otro objeto. Para crear uno, simplemente defina una clase que implemente los métodos de delegado que le interesen, y marque esa clase como implementando el protocolo de delegado.

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

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

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

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

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

Por UIWebViewotro lado, es probable que tenga un código similar para ver si el delegado responde al webViewDidStartLoad:mensaje respondsToSelector:y envíelo si corresponde.

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

La propiedad de delegado en sí misma generalmente se declara weak(en ARC) o assign(pre-ARC) para evitar retener bucles, ya que el delegado de un objeto a menudo contiene una fuerte referencia a ese objeto. (Por ejemplo, un controlador de vista es a menudo el delegado de una vista que contiene).

Hacer delegados para sus clases

Para definir sus propios delegados, deberá declarar sus métodos en algún lugar, como se explica en los Apple Docs sobre protocolos . Por lo general, declaras un protocolo formal. La declaración, parafraseada de 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 clase base abstracta, ya que crea un tipo especial para su delegado, UIWebViewDelegateen este caso. Los implementadores delegados tendrían que adoptar este protocolo:

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

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

Nombrando

Los métodos delegados normalmente se nombran comenzando con el nombre de la clase delegante y toman el objeto delegante como primer parámetro. También suelen utilizar una forma de voluntad, debería o no. Por lo tanto, webViewDidStartLoad:(el primer parámetro es la vista web) en lugar de loadStarted(sin tomar ningún parámetro), por ejemplo.

Optimizaciones de velocidad

En lugar de verificar si un delegado responde a un selector cada vez que queremos enviar un mensaje, puede almacenar esa información en caché cuando se configuran los delegados. Una manera muy limpia de hacer esto es usar un campo de bits, 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 maneje los mensajes accediendo a nuestra delegateRespondsToestructura, en lugar de enviarlos -respondsToSelector:una y otra vez.

Delegados informales

Antes de que existieran los protocolos, era común el uso de una categoría en la NSObjectque declare los métodos delegado podría implementar. Por ejemplo, CALayertodavía hace esto:

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

Esto básicamente le dice al compilador que cualquier objeto podría implementar displayLayer:.

Luego usaría el mismo -respondsToSelector:enfoque que el descrito anteriormente para llamar a este método. Los delegados simplemente implementan este método y asignan la delegatepropiedad, y eso es todo (no se declara que se ajusta a un protocolo). Este método es común en las bibliotecas de Apple, pero el nuevo código debe usar el enfoque de protocolo más moderno anterior, ya que este enfoque contamina NSObject(lo que hace que la autocompleta sea menos útil) y hace que sea difícil para el compilador advertir sobre errores tipográficos y similares.

Respondida el 09/03/2009 a las 17:16
fuente por usuario

votos
360

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

MyClass.h archivo debería tener este aspecto (añadir líneas de delegado 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

MyClass.m archivo debe tener este aspecto

#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 utilizar su delegado en otra clase (UIViewController llama 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 delegado

- (void) myClassDelegateMethod: (MyClass *) sender {
    NSLog(@"Delegates are great!");
}
Respondida el 30/09/2012 a las 11:25
fuente por usuario

votos
18

Cuando se utiliza el método de protocolo formal para la creación de apoyo a los delegados, he encontrado que se puede garantizar el tipo adecuado de control (aunque, tiempo de ejecución, no en tiempo de compilación) mediante la adición de algo así como:

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

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

Respondida el 04/05/2010 a las 21:42
fuente por usuario

votos
17

Tal vez esto sea más parecido a lo que te estás perdiendo:

Si vienes desde un punto de vista similar a C ++, los delegados tardan un poco en acostumbrarse, pero básicamente "simplemente funcionan".

La forma en que funciona es que estableces algún objeto que escribiste como delegado en NSWindow, pero tu objeto solo tiene implementaciones (métodos) para uno o algunos de los muchos métodos delegados posibles. Entonces sucede algo y NSWindowquiere llamar a su objeto, simplemente usa el respondsToSelectormétodo de Objective-c para determinar si su objeto quiere que se llame ese método, y luego lo llama. Así es como funciona Objective-c: los métodos se buscan a demanda.

Es totalmente trivial hacerlo con tus propios objetos, no hay nada especial, podrías tener, por ejemplo, NSArray27 objetos, todos los diferentes tipos de objetos, solo 18 de ellos tienen el método, -(void)setToBue;los otros 9 no. Entonces, para llamar setToBluea los 18 que lo necesitan, algo como esto:

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

La otra cosa acerca de los delegados es que no se retienen, por lo que siempre debe configurar el delegado nilen su MyClass deallocmétodo.

Respondida el 10/03/2009 a las 01:18
fuente por usuario

votos
16

¡Por favor! consulte más abajo sencillo tutorial paso a paso para entender cómo funciona delegados en IOS.

Delegado en IOS

He creado dos ViewControllers (para el envío de datos de uno a otro)

  1. FirstViewController implementar delegado (que proporciona datos).
  2. SecondViewController declarar el delegado (que van a recibir datos).
Respondida el 27/02/2013 a las 13:21
fuente por usuario

votos
15

Como buenas prácticas recomendadas por Apple, es bueno para el delegado (que es un protocolo, por definición), para cumplir con NSObjectel protocolo.

@protocol MyDelegate <NSObject>
    ...
@end

Y crear métodos opcionales dentro de su delegado (es decir, métodos que no necesariamente ser implementado), puede utilizar la @optionalanotación de la siguiente manera:

@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

Así que cuando se utilizan métodos que se han especificado como opcionales, es necesario (en su clase) consultar con respondsToSelectorsi la vista (que está cumpliendo con su delegado) ha puesto en marcha realmente su método opcional (s) o no.

Respondida el 04/08/2013 a las 09:39
fuente por usuario

votos
10

Creo que todas estas respuestas tienen mucho sentido una vez que entienda los delegados. En lo personal yo venía de la tierra de C / C ++ y antes de que los lenguajes procedimentales como Fortran, etc, así que aquí está mi 2 min toman en la búsqueda de análogos similares en C ++ paradigma.

Si tuviera que explicar a los delegados a un programador de C ++ / Java diría

¿Cuáles son los delegados? Estos son punteros estáticas a las clases dentro de otra clase. Una vez que se asigna un puntero, puede llamar a funciones / métodos de esa clase. De ahí que algunas funciones de su clase son "delegadas" (En el mundo de C ++ - puntero a un puntero de objeto de clase) a otra clase.

¿Cuáles son los protocolos? Conceptualmente, sirve al propósito de lo más similar al archivo de encabezado de la clase va a asignar como una clase de delegado. Un protocolo es una forma explícita de la definición de lo que debe ser implementado en la clase que es puntero se estableció como delegado dentro de una clase métodos.

¿Cómo puedo hacer algo similar en C ++? Si ha intentado hacer esto en C ++, sería mediante la definición de punteros a clases (objetos) en la definición de clase y luego efectuar sus conexiones a otras clases que proporcionan funciones adicionales como delegados a su clase base. Pero este cableado debe ser maitained dentro del código y será torpe y propenso a errores. Objetivo C simplemente asume que los programadores no son mejores en el mantenimiento de esta decipline y proporciona restricciones del compilador para hacer cumplir una aplicación limpia.

Respondida el 19/06/2013 a las 11:34
fuente por usuario

votos
9

versión Swift

Un delegado es sólo una clase que hace un trabajo para otra clase. Lea el siguiente código para un poco tonto (pero esperemos esclarecedor) Zona de juegos ejemplo 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 required 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 repquired 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 delegados se utilizan a menudo en las siguientes situaciones

  1. Cuando una clase necesita comunicar alguna información a otra clase
  2. Cuando una clase quiere permitir que otra clase para personalizarlo

Las clases no necesitan saber nada de antemano entre sí, excepto que la clase delegado cumpla con el protocolo requerido.

Le recomiendo la lectura de los dos artículos siguientes. Me ayudaron a entender los delegados, incluso mejor que la documentación lo hizo.

Respondida el 05/11/2015 a las 14:11
fuente por usuario

votos
8

digamos que usted tiene una clase que ha desarrollado y desea declarar una propiedad delegado para poder notificar cuando ocurre algún evento:

@class myClass;

@protocol myClassDelegate <NSObject>

-(void)myClass:(MyClass*)myObject requiredEventHandlerWithParameter:(ParamType*)param;

@optional
-(void)myClass:(MyClass*)myObject optionalEventHandlerWithParameter:(ParamType*)param;

@end


@interface MyClass : NSObject

@property(nonatomic,weak)id< MyClassDelegate> delegate;

@end

por lo que se declara un protocolo en el MyClassarchivo de cabecera (o un archivo de cabecera por separado), y declara los controladores de eventos requeridos / opcionales que el delegado debe / debería poner en práctica, a continuación, declarar una propiedad en MyClassel tipo ( id< MyClassDelegate>) que significa cualquier clase c objetivo que se ajusta a el protocolo MyClassDelegate, se dará cuenta de que la propiedad delegado se declara como débil, esto es muy importante para evitar retener ciclo (con mayor frecuencia el delegado conserva la MyClassinstancia por lo que si usted declaró el delegado que conservan, ambos se conservan entre sí y tampoco de ellos sabrá nunca ser puesto en libertad).

usted notará también que los métodos de protocolo pasa a la MyClassinstancia del delegado como parámetro, esto es la mejor práctica en caso de que el delegado quiere llamar a algunos métodos de MyClassinstancia y también ayuda cuando el delegado declara a sí misma como MyClassDelegatea varios MyClasscasos, como cuando tienes múltiples UITableView'sinstancias de su ViewControllery se declara como UITableViewDelegatea todos ellos.

y dentro de su MyClassnotifica al delegado con los eventos declarados de la siguiente manera:

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

primero se comprueba si su delegado responde al método de protocolo que está a punto de llamar en caso de que el delegado no ponerla en práctica y la aplicación se bloqueará entonces (incluso si es necesario el método de protocolo).

Respondida el 08/04/2015 a las 13:24
fuente por usuario

votos
8

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

Apenas práctica mis delegados, ya que rara vez necesito. Yo sólo puede tener un delegado para un objeto delegado. Así que si usted quiere que su delegado para una comunicación bidireccional / pasando los datos de lo que es mucho mejor de notificaciones.

NSNotification puede pasar objetos a más de uno destinatarios y es muy fácil de usar. Funciona así:

MyClass.m archivo debe tener este aspecto

#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 utilizar su notificación en otro clases: Agregar clase en calidad de 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 se olvide de quitar su clase como un observador si

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
Respondida el 17/07/2013 a las 05:58
fuente por usuario

votos
6

Este es un método simple para crear delegados

Crear Protocolo en el archivo .h. Asegúrese de que está definido el protocolo antes de usar @class seguido por el nombre de la UIViewController< As the protocol I am going to use is UIViewController class>.

Paso: 1: Crear un nuevo Protocolo de clase llamada "YourViewController" que será la subclase de la clase UIViewController y asignar esta clase para la segunda ViewController.

Paso 2: Ir al archivo "YourViewController" y modificarlo de la siguiente manera:

#import <UIKit/UIkit.h>
@class YourViewController;

@protocol YourViewController Delegate <NSObject>

 @optional
-(void)defineDelegateMethodName: (YourViewController *) controller;

@required
-(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 métodos definidos en el comportamiento del protocolo se pueden controlar con @optional y @Required como parte de la definición de protocolo.

Paso: 3: Aplicación de 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

// comprobar si el método se ha definido antes de llamar

 - (void) someMethodToCallDelegate {
     if ([[self delegate] respondsToSelector:@selector(defineDelegateMethodName:)]) {
           [self.delegate delegateMethodName:self]; 
     }
  }
Respondida el 29/09/2015 a las 06:23
fuente por usuario

votos
5

Para crear su propio delegado, primero es necesario crear un protocolo y declarar los métodos necesarios, sin implementar. Y luego aplicar este protocolo en su clase de cabecera en la que desea aplicar los métodos de delegado o delegados.

Un protocolo debe ser declarado como a continuación:

@protocol ServiceResponceDelegate <NSObject>

- (void) serviceDidFailWithRequestType:(NSString*)error;
- (void) serviceDidFinishedSucessfully:(NSString*)success;

@end

Esta es la clase de servicio en alguna tarea que debe hacerse. Se muestra cómo definir delegado y cómo configurar el delegado. En la clase de implementación después de que la tarea se ha completado del delegado de los métodos se llaman.

@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 principal clase de vista desde donde la clase de servicio se llama ajustando el delegado a sí mismo. Y también el protocolo se implementa en la clase de cabecera.

@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 aplicación de métodos de delegado de esta clase, el control va a volver una vez que la operación / tarea se realiza.

Respondida el 03/08/2015 a las 04:47
fuente por usuario

votos
1

Exención de responsabilidad: esta es la Swiftversión de cómo crear una delegate.

Así que, ¿cuáles son los delegados? ... en desarrollo de software, hay arquitecturas de soluciones reutilizables generales que ayudan a resolver los problemas que ocurren comúnmente en un contexto dado, estas “plantillas”, por así decirlo, son mejor conocidos como patrones de diseño. Los delegados son un patrón de diseño que permite un objeto a enviar mensajes a otro objeto cuando ocurre un evento específico. Imagínese un objeto A llama a un objeto B para realizar una acción. Una vez que la acción se ha completado, el objeto A debe saber que B ha completado la tarea y tomar las medidas necesarias, esto se puede lograr con la ayuda de los delegados!

Para una mejor explicación, voy a mostrar cómo crear un delegado a medida que pasa los datos entre las clases, con Swift en una sencilla aplicación, se inicia mediante la descarga o la clonación de este proyecto arranque y ejecutarlo!

Se puede ver una aplicación con dos clases, ViewController Ay ViewController B. B tiene dos puntos de vista que en el grifo cambia el color de fondo de la ViewController, nada demasiado complicado ¿verdad? Bueno, ahora vamos a pensar en una manera fácil de cambiar también el color de fondo de la clase A cuando se golpean ligeramente las vistas en la clase B.

El problema es que vistas son parte de la clase B y no tienen idea acerca de la clase A, así que tenemos que encontrar una manera de comunicarse entre estas dos clases, y ahí es donde brilla delegación. Dividí la aplicación en 6 pasos para que pueda utilizar esto como una hoja de trucos cuando lo necesite.

Paso 1: Busque la marca de paso pragma 1 en el archivo y añadir esta ClassBVC

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

El primer paso es crear una protocol, en este caso, vamos a crear el protocolo en la clase B, dentro del protocolo, puede crear tantas funciones que desee en base a los requerimientos de su aplicación. En este caso, simplemente tenemos una simple función que acepta un opcional UIColorcomo un argumento. Es una buena práctica para nombrar sus protocolos de añadir la palabra delegateal final del nombre de la clase, en este caso, ClassBVCDelegate.

Paso 2: Busque el paso marca Pragma 2 en ClassVBCy añade este

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

Aquí acabamos de crear una propiedad delegada de la clase, esta propiedad debe adoptar el protocoltipo, y que debería ser opcional. También, se debe añadir la palabra clave débil antes de la propiedad para evitar retener ciclos y potenciales pérdidas de memoria, si no sabes lo que significa que no se preocupe por ahora, sólo recuerda añadir esta palabra clave.

Paso 3: Busque el paso marca Pragma 3 dentro de la handleTap methoden ClassBVCy añade este

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

Una cosa que usted debe saber, ejecutar la aplicación y toque en cualquier caso, no podrá ver cualquier comportamiento nuevo y eso es correcto, pero lo que quiero señalar es que la aplicación no es chocar cuando el delegado se llama, y que es porque creamos como un valor opcional y es por eso que no se bloqueará incluso el delegado no existe todavía. Ahora vamos a ir a ClassAVCpresentar y que sea, la delegada.

Paso 4: Busque el paso marca Pragma 4 dentro del método handleTap en ClassAVCy añadir esta junto al tipo de clase como esta.

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

Ahora ClassAVC adoptó el ClassBVCDelegateprotocolo, se puede ver que el compilador te da un error que dice “Tipo 'ClassAVC no se ajusta al protocolo 'ClassBVCDelegate' y esto sólo significa que usted no ha utilizado los métodos del protocolo, sin embargo, imaginar que cuando la clase a adopta el protocolo es como firmar un contrato con la clase B y de este contrato dice “Cualquier clase adoptarme debe utilizar mis funciones!”

Nota rápida: Si usted viene de un Objective-Cfondo que está pensando probablemente que también se puede cerrar hasta que el error de hacer que el método opcional, pero para mi sorpresa, y probablemente el suyo, Swiftel lenguaje no soporta opcional protocols, si desea hacerlo puede crear una extensión para su protocolo utilizar la palabra clave @objc en su protocolaplicación.

Personalmente, si tengo que crear un protocolo con diferentes métodos opcionales que preferiría para dividirla en diferentes protocols, de esa manera voy a seguir el concepto de dar un solo responsabilidad de mis objetos, pero puede variar en función de la aplicación específica.

aquí es un buen artículo sobre métodos opcionales.

paso 5: Busque el paso marca pragma 5 dentro de la prepararse para el método de segue y añadir esta

//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í sólo estamos creando una instancia de ClassBVCy asignar su delegado a uno mismo, pero lo que es uno mismo aquí? así, yo es la ClassAVCque se ha delegado!

Paso 6: Por último, busque el paso 6 en Pragma ClassAVCy vamos a utilizar las funciones de la protocol, comienza a escribir func changeBackgroundColor y verá que se trata de auto-completar por usted. Se puede añadir cualquier aplicación en su interior, en este ejemplo, se acaba de cambiar el color de fondo, añadir esto.

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

Ahora ejecute la aplicación!

Delegatesestá en todas partes y es probable que los usa sin ni siquiera darse cuenta, si crea una tableviewen el pasado que utilizó la delegación, muchas clases de UIKITtrabajos alrededor de ellos y muchos otros frameworkstambién, que resuelven estos problemas principales.

  • Evitar el acoplamiento ajustado de objetos.
  • Modificar el comportamiento y la apariencia sin la necesidad de una subclase de objetos.
  • tareas permitirán a ser manejados fuera a cualquier objeto arbitrario.

Felicidades, usted acaba de poner en práctica un delegado de encargo, sé que usted está pensando probablemente, tantos problemas sólo para esto? así, la delegación es un patrón de diseño muy importante entender si quiere convertirse en un iOSdesarrollador, y siempre tener en cuenta que tienen relación uno a uno entre los objetos.

Se puede ver el tutorial original de aquí

Respondida el 26/04/2017 a las 02:27
fuente por usuario

votos
1

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{
}
Respondida el 19/12/2016 a las 01:14
fuente por usuario

votos
0

Respuesta es en realidad respondió, pero me gustaría darle una "hoja de trucos" para la creación de un delegado:

DELEGATE SCRIPT

CLASS A - Where delegate is calling function

@protocol <#Protocol Name#> <NSObject>

-(void)delegateMethod;

@end

@interface <#Some ViewController#> : <#UIViewController#> 

@property (nonatomic, assign) id <<#Protocol Name#>> delegate;

@end


@implementation <#Some ViewController#> 

-(void)someMethod {
    [self.delegate methodName];
}

@end




CLASS B - Where delegate is called 

@interface <#Other ViewController#> (<#Delegate Name#>) {}
@end

@implementation <#Other ViewController#> 

-(void)otherMethod {
    CLASSA *classA = [[CLASSA alloc] init];

    [classA setDelegate:self];
}

-delegateMethod() {

}

@end
Respondida el 16/03/2018 a las 01:40
fuente por usuario

votos
0

Vamos a empezar con un ejemplo, si compramos un producto en línea, pasa por procesos como el envío / entrega manejado por diferentes teams.So si el envío se ha completado, el equipo de envío debe notificar equipo de entrega y debe ser comunicación uno a uno como la difusión de esta información sería por encima de otras personas / proveedor puede ser que desee pasar esta información sólo a las personas requeridas.

Así que si pensamos en términos de nuestra aplicación, un evento puede ser un pedido en línea y diferentes equipos puede ser como múltiples puntos de vista.

Aquí está el código considere ShippingView como equipo y DeliveryView envío como equipo de entrega:

//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
        //
    }
}
Respondida el 14/07/2017 a las 07:14
fuente por usuario

votos
0

En mi punto de vista crear clase separada para ese método delegado y se puede utilizar en la que desea.

en mi DropDownClass.h personalizada

typedef enum
{
 DDSTATE,
 DDCITY
}DropDownType;

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

después de ese archivo in.m crear matriz con los objetos,

 - (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 isFiltered?[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];
        }
    }
}];
}

Aquí todos están destinados para personalizada class.after delegado que puede utilizar este método delegado donde want.for ejemplo ...

en mi otra importación viewcontroller después de eso

crear una acción para llamar método delegado como esto

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

después de que el método llamado delegado como esto

- (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;
}
}
Respondida el 08/02/2017 a las 06:30
fuente por usuario

votos
0
//1.
//Custom delegate 
@protocol TB_RemovedUserCellTag <NSObject>

-(void)didRemoveCellWithTag:(NSInteger)tag;

@end

//2.
//Create a weak reference in a class where you declared 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. Aplicar el método en la clase .m - (void) didRemoveCellWithTag: (NSInteger) etiqueta {@ NSLog ( "Tag% d", etiqueta);

}

Respondida el 02/01/2017 a las 13:31
fuente por usuario

votos
0

Delegar: - Crear

@protocol addToCartDelegate <NSObject>

-(void)addToCartAction:(ItemsModel *)itemsModel isAdded:(BOOL)added;

@end

Enviar y asigne delegado para ver quien está enviando datos

[self.delegate addToCartAction:itemsModel isAdded:YES];
Respondida el 08/12/2016 a las 07:50
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more