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.

Mytheral
fonte

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];
Cristian Radu
fonte
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()
}
canhazbits
fonte
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 ...

Sradforth
fonte
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"
mikemike396
fonte
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á.

Tunvir Rahman Tusher
fonte
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

bruno.yvan.morel
fonte
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.

ZaEeM ZaFaR
fonte
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;)

Daniele D.
fonte
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?
Marco Miltenburg
fonte
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

iAj
fonte
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];
Ada
fonte
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.

ingconti
fonte
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

Breno Medeiros de Oliveira
fonte