iOS - вызов метода делегирования приложения из ViewController


248

То, что я пытаюсь сделать, - это нажать кнопку (которая была создана в коде) и заставить ее вызвать другой контроллер представления, а затем запустить функцию в новом контроллере представления.

Я знаю, что это может быть сделано относительно легко в IB, но это не вариант.

Примером того, что я хочу сделать, было бы, если бы у вас было два контроллера представления, один с заставкой дома. На другом контроллере вида прошел дом, чтобы вы могли пройти через все комнаты в установленном порядке. На заставке будут кнопки для каждой комнаты, которые позволят вам прыгнуть в любую точку прохода.

Ответы:


538

Вы можете получить доступ к делегату следующим образом:

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

Замените MainClass именем класса вашего приложения.

Затем, если у вас есть свойство для другого контроллера представления, вы можете вызвать что-то вроде:

[appDelegate.viewController someMethod];

12
может также понадобиться импортировать файл appDelegate.h, где бы он ни использовался, или сделать @class appDelegate
Zaky German

3
Файл appDelegate.h является хорошим кандидатом для перехода в целевой префикс / предварительно скомпилированный заголовочный файл IMO.
Mharper

48
Если вы импортируете своего делегата приложения в свой Prefix.pch, например, @mharper говорит, что вы также можете добавить это одновременно: #define AppDelegate ((MyAppDelegateClass *) [UIApplication sharedApplication] .delegate), который затем позволяет вам получить доступ к вашему делегату приложения как '[AppDelegate.viewController someMethod]'. Это немного упрощает, но также облегчает злоупотребление им.
Кенни Лёврин

после @end моего файла делегата приложения я добавил #define AppDelegate ((MyAppDelegateClass *) [UIApplication sharedApplication] .delegate) Теперь любой делегат приложения класса может напрямую использовать [AppDelegate.viewController someMethod]
harveyslash

43

И если кому-то интересно, как это сделать в swift:

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

если пусть appDelegate = UIApplication.sharedApplication (). делегировать как? AppDelegate {} - лучший подход в swift.
cbartel

@petrsyn Что вы имеете в виду делегат может быть nil? Разве это не приложение ВСЕГДА имеет AppDelegate ?!
Мед

В последних версиях Swift, sharedApplication()следует заменить на shared. т.е. удалите «Приложение» и скобки. Таким образом, полный рабочий код на Swift 5.2 будет: if let myDelegate = UIApplication.shared.delegate as? AppDelegate { myDelegate.someMethod() }
sfarbota

41

Похоже, вам просто нужно UINavigationController настройка?

Вы можете получить в AppDelegateлюбом месте программы через

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

В вашем делегате приложения вы должны иметь свой контроллер навигации, либо через IB, либо в коде.

В коде, если вы уже создали свой viewcontroller «Обзор дома», это будет что-то вроде этого в вашем 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];

После этого вам просто нужен viewcontroller для каждой комнаты и вызывать следующее, когда происходит событие нажатия кнопки ...

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

Я не проверял приведенный выше код, поэтому простите за любые синтаксические ошибки, но надеюсь, что псевдокод поможет ...


8
Твой ответ тоже правильный, в итоге я использовал комбинацию Кристиана и твоего ответа. Я хотел бы разделить галочку.
Mytheral

15

Вот как я это делаю.

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

Не забудьте импортировать.

#import "AppDelegate.h"

13

Просто следуйте этим шагам

1. импортируйте ваш делегат приложения в ваш класс, где вы хотите объект делегата приложения.

#import "YourAppDelegate.h"

2. Внутри вашего класса создайте экземпляр объекта вашего делегата приложения (это в основном одноэлементный).

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

3. Теперь вызвать метод с помощью селектора

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

        [appDelegate yourMethod];
    }

или напрямую

[appDelegate yourMethod];

для быстрого

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

Я буду рекомендовать первый. Беги и иди.


это определенно НЕ новый экземпляр делегата, а скорее извлекающий одноэлементный делегат одноэлементного приложения
Ammo Goettsch

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

Избегайте включения вашего AppDelegate.h везде. Это простое приведение, которое проходит долгий путь, позволяя разрабатывать независимый контроллер и использовать его в других местах, не беспокоясь об имени класса и так далее ...

наслаждаться


Спасибо, что поделились, это радует меня на пару минут, вероятно, это будет работать каким-то образом, но что, если я захочу использовать метод вроде visibleViewController из этого? Это выдаст ошибку, подобную этой: Свойство visibleViewController не найдено для объекта типа NSObject <UIApplicationDelegate> *. какое-нибудь решение для этого?
mgyky

8

Много хороших ответов уже добавлено. Хотя я хочу добавить что-то, что подходит мне большую часть времени.

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

и это все. Используйте его во всем приложении, как константу.

например

[kAppDelegate methodName];

Не забудьте импортировать yourAppDelegate.h в соответствующий файл .pch или макрос.


7

Если кому-то нужно то же самое в Xamarin (Xamarin.ios / Monotouch), это сработало для меня:

var myDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;

(Требуется использование UIKit;)


Правильный оператор в Swift: пусть appdel: AppDelegate = UIApplication.shared.delegate as! AppDelegate
Фил,

5

И в случае, если вам нужен доступ к вашему делегату расширения WatchKit из контроллера представления на watchOS:

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

5

Обновление для Swift 3.0 и выше

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

    print("someMethodInAppDelegate called")
}

Вызов вышеуказанного метода из вашего контроллера следующим образом

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

    appDelegate.someMethodInAppDelegate()
}

Вывод:

введите описание изображения здесь


3

Вы можете добавить #define uAppDelegate (AppDelegate *)[[UIApplication sharedApplication] delegate]в Prefix.pchфайл вашего проекта, а затем вызвать любой из ваших методов AppDelegateв любом UIViewControllerс приведенным ниже кодом.

[uAppDelegate showLoginView];

0

Даже если это технически осуществимо, это НЕ хороший подход. Когда вы говорите: «Заставка будет иметь кнопки для каждой комнаты, которые позволят вам прыгнуть в любую точку прохода». Итак, вы хотите пройти через appdelegate для вызова этих контроллеров через события tohc на кнопках?

Этот подход не следует указаниям Apple и имеет много недостатков.


Посмотрите на дату вопроса ... Это было в то время, когда Интерфейсный Разработчик был отдельным приложением, а разработка была совсем другим чудовищем. Я много лет не занимался разработкой iOS, поэтому не могу оценить более современные ответы.
Mytheral

это может быть .. но мои соображения остаются в силе
ingconti

0

В 2020 году iOS13, xCode 11.3. Что работает для Objective-C:

#import "AppDelegate.h"

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

Это работает для меня, я надеюсь, что то же самое для вас! : D

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.