iOS - método Calling App Delegate do ViewController


248

O que estou tentando fazer é clicar em um botão (que foi criado no código) e chamar um controlador de exibição diferente e executar uma função no novo controlador de exibição.

Eu sei que isso poderia ser feito com relativa facilidade no IB, mas isso não é uma opção.

Um exemplo do que eu quero fazer seria se você tivesse dois controladores de exibição, um com uma tela inicial da casa. O outro controlador de vista deu uma volta pela casa e você pode percorrer todos os cômodos em uma ordem definida. A tela inicial teria botões para cada sala que permitiriam que você pulasse para qualquer ponto da caminhada.

Respostas:


538

Você pode acessar o delegado assim:

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

Substitua MainClass pelo nome da sua classe de aplicativo.

Então, desde que você tenha uma propriedade para o outro controlador de exibição, é possível chamar algo como:

[appDelegate.viewController someMethod];

12
pode também precisar importar o arquivo appDelegate.h onde quer que seja usado, ou fazer @class appDelegate
Zaky German

3
O arquivo appDelegate.h é um bom candidato para entrar no IMO do arquivo de cabeçalho de prefixo / pré-compilado do destino.
mharper

48
Se você importar o representante do seu aplicativo no seu Prefix.pch, como o @mharper diz que também poderá adicioná-lo ao mesmo tempo: #define AppDelegate ((MyAppDelegateClass *) [UIApplication sharedApplication] .delegate), que permite acessar o representante do aplicativo como '[AppDelegate.viewController someMethod]'. Isso simplifica um pouco, mas também facilita o abuso.
Kenny Lövrin

depois do @end do meu arquivo delegate.h do aplicativo, adicionei #define AppDelegate ((MyAppDelegateClass *) [UIApplication sharedApplication] .delegate) Agora, qualquer classe que importa o delegado do aplicativo pode usar diretamente [AppDelegate.viewController someMethod]
harveyslash

43

E se alguém está se perguntando como fazer isso swift:

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

se deixe delegar como appDelegate = UIApplication.sharedApplication ().? AppDelegate {} é uma abordagem melhor rapidamente.
Cbartel

@petrsyn O que você quer dizer com delegado nil? Não é que um aplicativo SEMPRE tenha um AppDelegate ?!
Mel

Nas versões recentes do Swift, sharedApplication()deve ser substituído por shared. ou seja, remova "Application" e os parênteses. Portanto, o código de trabalho completo a partir do Swift 5.2 seria: if let myDelegate = UIApplication.shared.delegate as? AppDelegate { myDelegate.someMethod() }
sfarbota

41

Parece que você só precisa de uma UINavigationControllerconfiguração?

Você pode acessar AppDelegatequalquer lugar do programa via

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

No delegado do aplicativo, você deve ter a configuração do controlador de navegação, via IB ou no código.

No código, supondo que você já tenha criado o seu controlador de exibição 'Visão geral da casa', seria algo parecido com isto em seu 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];

Depois disso, você só precisa de um controlador de exibição por 'sala' e invoca o seguinte quando um evento de clique no botão é selecionado ...

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

Eu não testei o código acima, então perdoe os erros de sintaxe, mas espero que o pseudo-código seja útil ...


8
Sua resposta também está correta. Acabei usando uma combinação de Cristian e sua resposta. Eu gostaria de poder dividir a marca de seleção.
Mytheral 22/02

15

É assim que eu faço.

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

Não se esqueça de importar.

#import "AppDelegate.h"

13

Basta seguir estas etapas

1.importe seu delegado de aplicativo em sua classe onde você deseja que o objeto seja delegado.

#import "YourAppDelegate.h"

2. dentro da sua classe, crie uma instância do objeto delegado do seu aplicativo (é basicamente um singleton).

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

Agora, invoque o método usando o seletor

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

        [appDelegate yourMethod];
    }

ou diretamente por

[appDelegate yourMethod];

para rápido

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

vou recomendar o primeiro. Corra e vá.


este é especificamente não uma nova instância do delegado, mas recupera o delegado singleton da aplicação Singleton
Ammo Goettsch

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

Evite ter que incluir seu AppDelegate.h em qualquer lugar. É um elenco simples que percorre um longo caminho, permitindo desenvolver um Controller independente e reutilizá-lo em outro lugar sem se preocupar com o nome da classe e assim por diante ...

Aproveitar


Obrigado por compartilhar, isso me deixa feliz por alguns minutos, provavelmente funcionará de alguma forma, mas e se eu quiser usar um método como visibleViewController? Ele dará um erro como este: A propriedade 'visibleViewController' não foi encontrada no objeto do tipo 'NSObject <UIApplicationDelegate> *. alguma solução para isso?
mgyky

8

Muitas boas respostas já foram adicionadas. Embora eu queira adicionar algo que me convenha a maior parte do tempo.

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

e é isso. Use-o em todo o aplicativo como uma constante.

por exemplo

[kAppDelegate methodName];

Não se esqueça de importar yourAppDelegate.h no arquivo .pch ou macros correspondente.


7

Se alguém precisar do mesmo no Xamarin (Xamarin.ios / Monotouch), isso funcionou para mim:

var myDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;

(Exigir o uso de UIKit;)


A declaração correta no Swift é appdel: AppDelegate = UIApplication.shared.delegate as! AppDelegate
Phil

5

E caso você precise acessar o delegado da extensão WatchKit em um controlador de exibição no watchOS:

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

5

Atualização para Swift 3.0 e superior

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

    print("someMethodInAppDelegate called")
}

chamando o método acima do seu controlador, seguindo

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

    appDelegate.someMethodInAppDelegate()
}

Resultado:

insira a descrição da imagem aqui


3

Você pode adicionar #define uAppDelegate (AppDelegate *)[[UIApplication sharedApplication] delegate]no Prefix.pcharquivo do seu projeto e, em seguida, chamar qualquer método seu AppDelegateem qualquer um UIViewControllercom o código abaixo.

[uAppDelegate showLoginView];

0

Mesmo se tecnicamente viável, NÃO é uma boa abordagem. Quando você diz: "A tela inicial possui botões para cada sala que permitem saltar para qualquer ponto da caminhada". Então, você deseja passar pelo appdelegate para chamar esses controladores via eventos tohc nos botões?

Essa abordagem não segue as diretrizes da Apple e apresenta muitas desvantagens.


Veja a data da pergunta ... É quando o Interface Builder era um aplicativo separado e o desenvolvimento era uma fera muito diferente. Não toquei no desenvolvimento do iOS há anos, então não posso avaliar respostas mais modernas.
Mytheral

ele ca ser .. mas as minhas considerações ainda são válidas
ingconti

0

Em 2020, iOS13, xCode 11.3. O que está funcionando para o Objective-C é:

#import "AppDelegate.h"

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

Está funcionando para mim, espero o mesmo para você! : D

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.