iOS - виклик методу делегата додатка від ViewController


248

Що я намагаюся зробити, це натиснути кнопку (яка була створена в коді) і запропонувати їй викликати інший контролер перегляду, а потім запустити функцію в новому контролері перегляду.

Я знаю, що це можна зробити порівняно легко в ІБ, але це не варіант.

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

Відповіді:


538

Ви можете отримати доступ до делегата так:

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

Замініть MainClass на ім'я вашого класу додатків.

Потім, якщо у вас є властивість для іншого контролера перегляду, ви можете зателефонувати на зразок:

[appDelegate.viewController someMethod];

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

3
Файл appDelegate.h є хорошим кандидатом, щоб перейти в цільовий префікс / попередньо складений заголовок IMO-файл.
mharper

48
Якщо ви імпортуєте делегата додатка у свій Prefix.pch, як-от @mharper, ви можете також додати його одночасно: #define AppDelegate ((MyAppDelegateClass *) [UIApplication sharedApplication] .delegate), який дозволяє вам отримати доступ до делегата програми, наприклад '[AppDelegate.viewController someMethod]'. Це трохи спрощує його, але також полегшує його зловживання.
Кенні Леврін

після @end мого файлу delegate.h програми, я додав #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 {} - кращий підхід.
cbartel

@petrsyn Яким ти можеш бути делегат nil? Хіба це не у додатку ВЖЕ є AppDelegate ?!
Мед

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

41

Здається, що вам просто потрібна UINavigationControllerустановка?

Ви можете отримати AppDelegateбудь-де в програмі через

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

У делегата програми вам слід налаштувати свій навігаційний контролер, або через ІБ, або в код.

У коді, якщо припустити, що ви створили свій контрольний перегляд "Огляд дому", це було б щось подібне у вашому 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];

Після цього вам просто знадобиться контролер перегляду на "кімнату" і викликати наступне, коли підбирається подія натискання кнопки ...

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

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


8
Ваша відповідь також правильна, я закінчила використання комбінації Крістіана та вашої відповіді. Я б хотів, щоб я міг розділити галочку.
Мітеральна

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

я порекомендую перший. Біжи і йди.


це спеціально НЕ новий екземпляр делегата, а скоріше витягує одиночний делегат програми Singleton
Ammo Goettsch

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

Уникайте необхідності включати ваш AppDelegate.h скрізь. Це простий склад, який проходить довгий шлях, що дозволяє розробити незалежний контролер і використовувати їх в інших місцях, не турбуючись про назву класу тощо.

Насолоджуйтесь


Дякую за те, що ви поділилися, це мене радує пару хвилин, імовірно, воно буде працювати якось, але що робити, якщо я хочу використовувати з нього такий метод, як видимийViewController? Це призведе до такої помилки: Властивість 'visibleViewController' не знайдено на об’єкті типу 'NSObject <UIApplicationDelegate> *. будь-яке рішення для цього?
mgyky

8

Дуже багато хороших відповідей уже додано. Хоча я хочу додати те, що мені найбільше підходить.

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

і це все. Використовуйте його протягом усього додатка так само, як постійне.

напр

[kAppDelegate methodName];

Не забудьте імпортувати вашAppDelegate.h у відповідний .pch або макрос-файл.


7

Якщо комусь потрібно те саме в Xamarin (Xamarin.ios / Monotouch), це працювало для мене:

var myDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;

(Потрібно використовувати UIKit;)


Правильне твердження у Swift - це нехай додаток: AppDelegate = UIApplication.shared.delegate як! 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 і має чимало недоліків.


Подивіться на дату питання ... Це ще з тих пір, коли Interface Builder був окремим додатком, а розробка - зовсім іншим звіром. Я не торкався розвитку 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.