iOS: chiamata del metodo delegato app da ViewController


248

Quello che sto cercando di fare è fare clic su un pulsante (che è stato creato nel codice) e farlo richiamare un controller di visualizzazione diverso, quindi far funzionare una funzione nel nuovo controller di visualizzazione.

So che potrebbe essere fatto relativamente facilmente in IB ma non è un'opzione.

Un esempio di ciò che voglio fare sarebbe se tu avessi due controller di visualizzazione uno con una schermata iniziale di casa. L'altro controller della vista aveva attraversato la casa per poter attraversare tutte le stanze in un ordine prestabilito. La schermata iniziale avrebbe pulsanti per ogni stanza che ti permetterebbero di saltare a qualsiasi punto della passeggiata.

Risposte:


538

Puoi accedere al delegato in questo modo:

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

Sostituisci MainClass con il nome della tua classe di applicazione.

Quindi, a condizione che tu abbia una proprietà per l'altro controller di visualizzazione, puoi chiamare qualcosa del tipo:

[appDelegate.viewController someMethod];

12
potrebbe anche essere necessario importare il file appDelegate.h ovunque venga utilizzato, oppure fare @class appDelegate
Zaky tedesco

3
Il file appDelegate.h è un buon candidato per andare nel file di intestazione prefisso / precompilato IMO del target.
mharper,

48
Se importi il ​​tuo delegato dell'app nel tuo Prefix.pch come @mharper dice che puoi anche aggiungere questo contemporaneamente: #define AppDelegate ((MyAppDelegateClass *) [UIApplication sharedApplication] .delegate) che ti consente quindi di accedere al tuo delegato dell'app come '[AppDelegate.viewController someMethod]'. Lo semplifica un po ', ma facilita anche l'abuso.
Kenny Lövrin,

dopo l'invio del file delegate.h della mia app, ho aggiunto #define AppDelegate ((MyAppDelegateClass *) [UIApplication sharedApplication] .delegate) Ora qualunque classe importa il delegato dell'app direttamente può usare [AppDelegate.viewController someMethod]
harveyslash

43

E se qualcuno si sta chiedendo come farlo in swift:

if let myDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
   myDelegate.someMethod()
}

if let appDelegate = UIApplication.sharedApplication (). delegate as? AppDelegate {} è un approccio migliore in tempi rapidi.
cbartel,

@petrsyn Cosa intendi dire che può essere il delegato nil? Un'app non ha SEMPRE un delegato per l'app ?!
Miele,

Nelle recenti versioni di Swift, sharedApplication()dovrebbe essere sostituito con shared. ad esempio, rimuovere "Applicazione" e le parentesi. Quindi il codice di lavoro completo a partire da Swift 5.2 sarebbe: if let myDelegate = UIApplication.shared.delegate as? AppDelegate { myDelegate.someMethod() }
sfarbota,

41

Sembra che tu abbia solo bisogno di una UINavigationControllerconfigurazione?

Puoi ottenere AppDelegateovunque nel programma tramite

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

Nel delegato dell'app dovresti avere il tuo controller di navigazione configurato, tramite IB o nel codice.

Nel codice, supponendo che tu abbia già creato il tuo viewcontroller "Panoramica della casa" sarebbe qualcosa di simile nel tuo 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];

Dopodiché ti basta un viewcontroller per 'room' e invocare quanto segue quando viene raccolto un evento click-button ...

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

Non ho testato il codice sopra quindi perdonare eventuali errori di sintassi ma spero che lo pseudo codice sia di aiuto ...


8
Anche la tua risposta è corretta, ho finito per usare una combinazione di Cristian e la tua risposta. Vorrei poter dividere il segno di spunta.
Mytheral,

15

Questo è come lo faccio.

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

Non dimenticare di importare.

#import "AppDelegate.h"

13

Segui questi passaggi

1.importare il delegato dell'app nella classe in cui si desidera l'oggetto delegato dell'app.

#import "YourAppDelegate.h"

2. all'interno della classe creare un'istanza dell'oggetto delegato dell'app (in pratica è un singleton).

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

3.Ora invoca il metodo usando il selettore

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

        [appDelegate yourMethod];
    }

o direttamente da

[appDelegate yourMethod];

per rapido

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

consiglierò il primo. Corri e vai.


questa NON è specificamente una nuova istanza del delegato, ma piuttosto recupera il delegato singleton dell'applicazione singleton
Ammo Goettsch,

11
NSObject <UIApplicationDelegate> * universalAppDelegate = 
    ( NSObject <UIApplicationDelegate> * ) [ [ UIApplication sharedApplication ] delegate ];

Evita di includere AppDelegate.h ovunque. È un cast semplice che consente di sviluppare controller indipendenti e riutilizzarli altrove senza preoccuparsi del nome della classe e così via ...

Godere


Grazie per la condivisione, mi rende felice per un paio di minuti, probabilmente funzionerà in qualche modo, ma cosa succede se voglio usare un metodo come visibleViewController da esso? Darà un errore del genere: Proprietà 'visibleViewController' non trovata sull'oggetto di tipo 'NSObject <UIApplicationDelegate> *. qualche soluzione per questo?
mgyky,

8

Molte buone risposte sono già state aggiunte. Anche se voglio aggiungere qualcosa che mi si addice per la maggior parte del tempo.

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

e questo è tutto. Usalo in tutta l'applicazione come una costante.

per esempio

[kAppDelegate methodName];

Non dimenticare di importare YourAppDelegate.h nel corrispondente file .pch o macro.


7

Se qualcuno ha bisogno dello stesso in Xamarin (Xamarin.ios / Monotouch), questo ha funzionato per me:

var myDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;

(Richiede l'utilizzo di UIKit;)


L'istruzione corretta in Swift è lasciare appdel: AppDelegate = UIApplication.shared.delegate as! AppDelegate
Phil

5

E nel caso in cui sia necessario accedere al delegato dell'estensione WatchKit da un controller di visualizzazione su watchOS:

extDelegate = WKExtension.sharedExtension().delegate as WKExtensionDelegate?

5

Aggiornamento per Swift 3.0 e versioni successive

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

    print("someMethodInAppDelegate called")
}

chiamando il metodo sopra dal controller seguendo le seguenti istruzioni

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

    appDelegate.someMethodInAppDelegate()
}

Produzione:

inserisci qui la descrizione dell'immagine


3

È possibile aggiungere #define uAppDelegate (AppDelegate *)[[UIApplication sharedApplication] delegate]il Prefix.pchfile del progetto e quindi chiamare qualsiasi metodo AppDelegatein qualsiasi UIViewControllercon il seguente codice.

[uAppDelegate showLoginView];

0

Anche se tecnicamente fattibile, NON è un buon approccio. Quando dici: "La schermata iniziale avrebbe pulsanti per ogni stanza che ti permetterebbero di saltare in qualsiasi punto del passaggio." Quindi vuoi passare attraverso il delegato dell'app per chiamare questi controller tramite eventi toc sui pulsanti?

Questo approccio non segue le linee guida di Apple e presenta molti inconvenienti.


Guarda la data sulla domanda ... È di quando quando Interface Builder era un'applicazione separata e lo sviluppo era una bestia molto diversa. Non tocco lo sviluppo di iOS da anni, quindi non posso valutare risposte più moderne.
Mytheral,

può essere .. ma le mie considerazioni sono ancora valide
ingconti

0

Nel 2020, iOS13, xCode 11.3. Ciò che funziona per Objective-C è:

#import "AppDelegate.h"

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

Funziona per me, spero lo stesso per te! : D

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.