iOS-从ViewController调用App Delegate方法


248

我想做的是单击一个按钮(它是用代码创建的),并让它调用另一个视图控制器,然后让它在新的视图控制器中运行一个功能。

我知道可以在IB中相对轻松地完成此操作,但这不是一个选择。

我想做的一个例子是,如果您有两个视图控制器,其中一个带有启动画面。另一个视图控制器在其上进行了遍历,您可以按设置的顺序遍历所有房间。初始屏幕上每个房间都有按钮,可让您跳至遍历中的任何点。

Answers:


538

您可以像这样访问委托:

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

用您的应用程序类的名称替换MainClass

然后,如果您拥有另一个视图控制器的属性,则可以调用以下代码:

[appDelegate.viewController someMethod];

12
无论使用在哪里,也可能需要导入appDelegate.h文件,或者执行@class appDelegate
Zaky German

3
appDelegate.h文件非常适合放入目标的前缀/预编译头文件IMO中。
mharper 2011年

48
如果您像@mharper一样将自己的应用程序委托导入Prefix.pch中,也可以同时添加:#define AppDelegate(((MyAppDelegateClass *)[UIApplication sharedApplication] .delegate),它允许您像这样访问您的应用程序委托“ [AppDelegate.viewController someMethod]”。它稍微简化了它,但也使它更易于滥用。
肯尼·洛夫林(KennyLövrin)2011年

在我的应用程序委托.h文件的@end之后,我添加了#define AppDelegate((MyAppDelegateClass *)[UIApplication sharedApplication] .delegate)现在,无论哪个类导入应用程序委托都可以直接使用[AppDelegate.viewController someMethod]
harveyslash

42

如果有人想知道如何执行以下操作swift

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

如果让appDelegate = UIApplication.sharedApplication()。delegate为?AppDelegate {}是快速的更好方法。
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或代码来设置导航控制器。

在代码中,假设您已经创建了“房屋概览”视图控制器,则在您的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。这是一个很简单的强制转换,可以走很长一段路,允许开发独立的Controller并在其他地方重用它们,而不必担心类名等等。

请享用


感谢您的分享,这让我开心了几分钟,也许它可以以某种方式工作,但是如果我想从中使用诸如visibleViewController之类的方法呢?它将给出如下错误:在'NSObject <UIApplicationDelegate> *类型的对象上找不到属性'visibleViewController'。有什么解决办法吗?
mgyky

8

已经添加了很多很好的答案。尽管我想添加适合大多数时间的内容。

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

就是这样。像在常量中一样在整个应用程序中使用它。

例如

[kAppDelegate methodName];

不要忘记在相应的.pch或宏文件中导入yourAppDelegate.h。


7

如果有人在Xamarin(Xamarin.ios / Monotouch)中需要相同的软件,这对我有用:

var myDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;

(需要使用UIKit;)


Swift中正确的语句是让appdel:AppDelegate = UIApplication.shared.delegate as!AppDelegate
Phil

5

如果需要从watchOS上的视图控制器访问WatchKit扩展代理,请执行以下操作:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.