iOS - metoda wywoływania aplikacji delegowanej z ViewController


248

Staram się kliknąć przycisk (utworzony w kodzie) i wywołać inny kontroler widoku, a następnie uruchomić funkcję w nowym kontrolerze widoku.

Wiem, że można to zrobić stosunkowo łatwo w IB, ale nie jest to opcja.

Przykładem tego, co chciałbym zrobić, byłoby posiadanie dwóch kontrolerów widoku, jednego z ekranem powitalnym domu. Drugi kontroler widoku miał po domu przejście, przez które można było przejść przez wszystkie pokoje w ustalonej kolejności. Ekran powitalny miałby przyciski dla każdego pokoju, które pozwoliłyby ci przejść do dowolnego punktu na przejściu.

Odpowiedzi:


538

Możesz uzyskać dostęp do delegata w następujący sposób:

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

Zamień MainClass na nazwę swojej klasy aplikacji.

Następnie, pod warunkiem, że masz właściwość dla drugiego kontrolera widoku, możesz wywołać coś takiego:

[appDelegate.viewController someMethod];

12
być może trzeba będzie zaimportować plik appDelegate.h, gdziekolwiek jest on używany, lub zrobić @class appDelegate
Zaky niemiecki

3
Plik appDelegate.h jest dobrym kandydatem do wejścia w IMO prefiksu / prekompilowanego pliku nagłówkowego.
mharper

48
Jeśli importujesz delegata aplikacji do Prefix.pch, jak @mharper mówi, że możesz również dodać to w tym samym czasie: #define AppDelegate ((MyAppDelegateClass *) [UIApplication sharedApplication] .delegate), który następnie umożliwia dostęp do Twojego delegata aplikacji, jak „[AppDelegate.viewController someMethod]”. To trochę upraszcza, ale także ułatwia nadużywanie.
Kenny Lövrin,

po @end mojego pliku delegate.h dodałem #define AppDelegate ((MyAppDelegateClass *) [UIApplication sharedApplication] .delegate) Teraz, niezależnie od tego, która klasa importuje aplikację, delegat aplikacji może bezpośrednio używać [AppDelegate.viewController someMethod]
harveyslash

43

A jeśli ktoś zastanawia się, jak to zrobić w swift:

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

if let appDelegate = UIApplication.sharedApplication (). delegować jako? AppDelegate {} to szybsze podejście.
cartart

@petrsyn Co masz na myśli, że delegatem może być nil? Czy to nie aplikacja ZAWSZE ma AppDelegate ?!
Honey

W najnowszych wersjach Swift sharedApplication()należy go zastąpić shared. tj. usuń „Aplikacja” i nawiasy. Tak więc pełny działający kod od Swift 5.2 byłby następujący: if let myDelegate = UIApplication.shared.delegate as? AppDelegate { myDelegate.someMethod() }
sfarbota

41

Brzmi jak potrzebujesz UINavigationControllerkonfiguracji?

Możesz uzyskać dostęp do AppDelegatedowolnego miejsca w programie za pośrednictwem

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

W aplikacji delegowanej powinieneś mieć skonfigurowany kontroler nawigacyjny za pośrednictwem IB lub kodu.

W kodzie, zakładając, że już utworzyłeś kontroler widoku „Przegląd domu”, byłoby to coś takiego w twoim 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];

Po tym potrzebujesz tylko kontrolera widoku na „pokój” i wywołujesz następujące zdarzenia, gdy zostanie odebrane zdarzenie kliknięcia przycisku ...

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

Nie testowałem powyższego kodu, więc wybacz mi błędy składniowe, ale mam nadzieję, że pseudo kod pomoże ...


8
Twoja odpowiedź jest również poprawna, w końcu użyłem kombinacji Cristiana i twojej odpowiedzi. Chciałbym podzielić znak zaznaczenia.
Mytheral

15

Tak to robię.

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

Nie zapomnij zaimportować.

#import "AppDelegate.h"

13

Wystarczy wykonać następujące kroki

1. zaimportuj delegata aplikacji na zajęcia, do których chcesz przekazać obiekt aplikacji.

#import "YourAppDelegate.h"

2. wewnątrz klasy utwórz instancję obiektu delegowania aplikacji (jest to w zasadzie singleton).

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

3. Teraz wywołaj metodę za pomocą selektora

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

        [appDelegate yourMethod];
    }

lub bezpośrednio przez

[appDelegate yourMethod];

dla szybkiego

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

polecę pierwszy. Uruchom i idź.


nie jest to specjalnie nowa instancja delegata, ale raczej pobiera delegata singletona aplikacji singleton
Ammo Goettsch

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

Unikaj konieczności dołączania AppDelegate.h wszędzie. To prosta obsada, która przechodzi długą drogę, umożliwiając opracowanie niezależnego kontrolera i ponowne użycie go w innym miejscu bez obawy o nazwę klasy i tak dalej ...

Cieszyć się


Dziękuję za udostępnienie, sprawia mi radość przez kilka minut, prawdopodobnie będzie to działać jakoś, ale co jeśli chcę użyć z niego metody takiej jak visibleViewController? Daje taki błąd: nie znaleziono właściwości „visibleViewController” w obiekcie typu „NSObject <UIApplicationDelegate> *. jakieś rozwiązanie tego?
mgyky,

8

Wiele dobrych odpowiedzi zostało już dodanych. Chociaż chcę dodać coś, co najbardziej mi odpowiada.

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

i to wszystko. Używaj go w całej aplikacji, tak jak na stałe.

na przykład

[kAppDelegate methodName];

Nie zapomnij zaimportować pliku yourAppDelegate.h do odpowiedniego pliku .pch lub makra.


7

Jeśli ktoś potrzebuje tego samego w Xamarin (Xamarin.ios / Monotouch), działało to dla mnie:

var myDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;

(Wymagaj użycia UIKit;)


Prawidłowa instrukcja w Swift pozwala appdel: AppDelegate = UIApplication.shared.delegate as! AppDelegate
Phil

5

A jeśli potrzebujesz dostępu do rozszerzenia rozszerzenia WatchKit z kontrolera widoku w systemie watchOS:

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

5

Aktualizacja do wersji Swift 3.0 i nowszej

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

    print("someMethodInAppDelegate called")
}

wywołanie powyższej metody z kontrolera przez następujące czynności

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

    appDelegate.someMethodInAppDelegate()
}

Wynik:

wprowadź opis zdjęcia tutaj


3

Możesz dodać plik #define uAppDelegate (AppDelegate *)[[UIApplication sharedApplication] delegate]swojego projektu, Prefix.pcha następnie wywołać dowolną metodę AppDelegatew dowolnym UIViewControllerz poniższym kodem.

[uAppDelegate showLoginView];

0

Nawet jeśli jest to technicznie wykonalne, NIE jest dobrym podejściem. Kiedy mówisz: „Ekran powitalny miałby przyciski dla każdego pokoju, które pozwoliłyby ci przejść do dowolnego punktu na przejściu”. Więc chcesz przejść przez appdelegate, aby wywołać te kontrolery poprzez zdarzenia tohc na przyciskach?

To podejście nie jest zgodne z wytycznymi Apple i ma wiele wad.


Spójrz na datę pytania ... To było od czasów, gdy Interface Builder był osobną aplikacją, a rozwój był zupełnie inną bestią. Od lat nie miałem styczności z programowaniem iOS, więc nie mogę ocenić bardziej nowoczesnych odpowiedzi.
Mytheral

może być .. ale moje rozważania są nadal aktualne
ingconti

0

W 2020 roku iOS13, xCode 11.3. W Objective-C działa:

#import "AppDelegate.h"

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

Działa dla mnie, mam nadzieję, że to samo dla ciebie! :RE

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.