iOS: método de delegado de aplicación de llamada desde ViewController

248

Lo que estoy tratando de hacer es hacer clic en un botón (que se creó en el código) y hacer que llame a un controlador de vista diferente y luego ejecutar una función en el nuevo controlador de vista.

Sé que podría hacerse con relativa facilidad en IB, pero esa no es una opción.

Un ejemplo de lo que quiero hacer sería si tuviera dos controladores de vista, uno con una pantalla de inicio de la casa. El otro controlador de vista tenía un recorrido por la casa en el que podía pasar por todas las habitaciones en un orden establecido. La pantalla de bienvenida tendría botones para cada habitación que te permitirían saltar a cualquier punto del recorrido.

Miteral
fuente

Respuestas:

538

Puede acceder al delegado de esta manera:

MainClass *appDelegate = (MainClass *)[[UIApplication sharedApplication] delegate];

Reemplace MainClass con el nombre de su clase de aplicación.

Luego, siempre que tenga una propiedad para el otro controlador de vista, puede llamar a algo como:

[appDelegate.viewController someMethod];
Cristian Radu
fuente
12
también podría necesitar importar el archivo appDelegate.h donde sea que se use, o hacer @class appDelegate
Zaky German
3
El archivo appDelegate.h es un buen candidato para ir en el prefijo de destino / archivo de encabezado precompilado IMO.
mharper
48
Si importa su delegado de aplicaciones en su Prefix.pch como @mharper dice que también puede agregar esto al mismo tiempo: #define AppDelegate ((MyAppDelegateClass *) [UIApplication sharedApplication] .delegate) que luego le permite acceder a su delegado de aplicaciones como '[AppDelegate.viewController someMethod]'. Lo simplifica un poco, pero también hace que sea más fácil abusar de él.
Kenny Lövrin
después del @end de mi aplicación delegate.h, agregué #define AppDelegate ((MyAppDelegateClass *) [UIApplication sharedApplication] .delegate) Ahora cualquier delegado de aplicación de importación de clase puede usar directamente [AppDelegate.viewController someMethod]
harveyslash
43

Y si alguien se pregunta cómo hacer esto en swift:

if let myDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
   myDelegate.someMethod()
}
canhazbits
fuente
si deja que appDelegate = UIApplication.sharedApplication (). delegue como? AppDelegate {} es un mejor enfoque en Swift.
cbartel
@petrsyn ¿Qué quieres decir con que el delegado puede ser nil? ¿No es eso una aplicación SIEMPRE tiene un AppDelegate?
Miel
En versiones recientes de Swift, sharedApplication()debe reemplazarse por shared. es decir, elimine "Aplicación" y los paréntesis. Entonces, el código de trabajo completo a partir de Swift 5.2 sería: if let myDelegate = UIApplication.shared.delegate as? AppDelegate { myDelegate.someMethod() }
sfarbota
41

¿Parece que solo necesitas una UINavigationControllerconfiguración?

Puede obtenerlo AppDelegateen cualquier parte del programa a través de

YourAppDelegateName* blah = (YourAppDelegateName*)[[UIApplication sharedApplication]delegate];

En su delegado de aplicaciones, debe tener la configuración del controlador de navegación, ya sea a través de IB o en código.

En el código, suponiendo que haya creado su controlador de vista 'Visión general de la casa' ya sería algo así en su AppDelegate didFinishLaunchingWithOptions...

self.m_window = [[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds] autorelease];
self.m_navigationController = [[[UINavigationController alloc]initWithRootViewController:homeViewController]autorelease];
[m_window addSubview:self.m_navigationController.view];

Después de esto, solo necesita un controlador de vista por 'habitación' e invocar lo siguiente cuando se selecciona un evento de clic de botón ...

YourAppDelegateName* blah = (YourAppDelegateName*)[[UIApplication sharedApplication]delegate];
[blah.m_navigationController pushViewController:newRoomViewController animated:YES];

No he probado el código anterior, así que perdona los errores de sintaxis, pero espero que el pseudocódigo sea de ayuda ...

sradforth
fuente
8
Tu respuesta también es correcta, terminé usando una combinación de Cristian y tu respuesta. Desearía poder dividir la marca de verificación.
Mytheral
15

Así es como lo hago.

[[[UIApplication sharedApplication] delegate] performSelector:@selector(nameofMethod)];

No te olvides de importar.

#import "AppDelegate.h"
mikemike396
fuente
13

Solo sigue estos pasos

1. Importe su delegado de aplicaciones en su clase donde desee el objeto delegado de aplicaciones.

#import "YourAppDelegate.h"

2.dentro de su clase, cree una instancia del objeto delegado de su aplicación (es básicamente un singleton).

YourAppDelegate *appDelegate=( YourAppDelegate* )[UIApplication sharedApplication].delegate;

3.Ahora invoque el método usando el selector

if([appDelegate respondsToSelector:@selector(yourMethod)]){

        [appDelegate yourMethod];
    }

o directamente por

[appDelegate yourMethod];

para rápido

let appdel : AppDelegate = UIApplication.shared.delegate as! AppDelegate

Recomendaré el primero. Corre y vete.

Tunvir Rahman Tusher
fuente
esta NO es específicamente una nueva instancia del delegado, sino que recupera el delegado singleton de la aplicación singleton
Ammo Goettsch
11
NSObject <UIApplicationDelegate> * universalAppDelegate = 
    ( NSObject <UIApplicationDelegate> * ) [ [ UIApplication sharedApplication ] delegate ];

Evita tener que incluir tu AppDelegate.h en todas partes. Es un elenco simple que recorre un largo camino, lo que permite desarrollar un controlador independiente y reutilizarlos en otro lugar sin preocuparse por el nombre de la clase, etc.

Disfrutar

bruno.yvan.morel
fuente
Gracias por compartir, me hace feliz por un par de minutos, probablemente funcionará de alguna manera, pero ¿qué pasa si quiero usar un método como visibleViewController? Dará un error como este: la propiedad 'visibleViewController' no se encuentra en el objeto de tipo 'NSObject <UIApplicationDelegate> *. alguna solución para esto?
mgyky
8

Ya se han agregado muchas buenas respuestas. Aunque quiero agregar algo que me convenga la mayor parte del tiempo.

#define kAppDelegate ((YourAppDelegate *)[[UIApplication sharedApplication] delegate]);

y eso es. Úselo en toda la aplicación como una constante.

p.ej

[kAppDelegate methodName];

No olvide importar yourAppDelegate.h en el archivo .pch o macros correspondiente.

ZaEeM ZaFaR
fuente
7

Si alguien necesita lo mismo en Xamarin (Xamarin.ios / Monotouch), esto funcionó para mí:

var myDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;

(Requiere usar UIKit;)

Daniele D.
fuente
La declaración correcta en Swift es dejar appdel: AppDelegate = UIApplication.shared.delegate as! AppDelegate
Phil
5

Y en caso de que necesite acceso a su delegado de extensión WatchKit desde un controlador de vista en watchOS:

extDelegate = WKExtension.sharedExtension().delegate as WKExtensionDelegate?
Marco Miltenburg
fuente
5

Actualización para Swift 3.0 y superior

//
// Step 1:- Create a method in AppDelegate.swift
//
func someMethodInAppDelegate() {

    print("someMethodInAppDelegate called")
}

llamando al método anterior desde su controlador siguiendo

//
// Step 2:- Getting a reference to the AppDelegate & calling the require method...
//
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {

    appDelegate.someMethodInAppDelegate()
}

Salida:

ingrese la descripción de la imagen aquí

iAj
fuente
3

Usted puede agregar #define uAppDelegate (AppDelegate *)[[UIApplication sharedApplication] delegate]en su proyecto de Prefix.pcharchivo y luego llamar a cualquier método de su AppDelegateen cualquiera UIViewControllercon el siguiente código.

[uAppDelegate showLoginView];
Ada
fuente
0

Incluso si es técnicamente factible, NO es un buen enfoque. Cuando dices: "La pantalla de bienvenida tendría botones para cada habitación que te permitirían saltar a cualquier punto del recorrido". Entonces, ¿desea pasar por appdelegate para llamar a estos controladores a través de eventos tohc en los botones?

Este enfoque no sigue las pautas de Apple y tiene muchos inconvenientes.

ingconti
fuente
Mire la fecha de la pregunta ... Es de cuando el Generador de interfaces era una aplicación separada y el desarrollo era una bestia muy diferente. No he tocado el desarrollo de iOS en años, así que no puedo evaluar respuestas más modernas.
Mytheral
ca que sea .. pero mis consideraciones siguen siendo válidas
ingconti
0

En 2020, iOS13, xCode 11.3. Lo que funciona para Objective-C es:

#import "AppDelegate.h"

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

Está funcionando para mí, ¡espero lo mismo para ti! :RE

Breno Medeiros de Oliveira
fuente