如何在app delegate中调用视图控制器中的方法?

时间:2017-04-22 23:54:27

标签: ios swift

我需要在AppDelegate的ViewController类中调用一个方法。这就是方法的样子:

var vc = ViewController()
self.vc.myFunction()

我尝试过使用window.rootViewController,但它告诉我myFunction方法不存在,因为rootViewController的类型为UIViewController。

我也试过

class AppDelegate: UIResponder, UIApplicationDelegate {

    func handleEvent() {
        if UIApplication.shared.applicationState == .active {
            // call myFunction()
        }
        else {
            ...
        }
    }
}

但这是创建一个ViewController类的新实例,这也不是我想要的。

以下是AppDelegate代码中我需要调用myFunction的部分:

{{1}}

上下文: 我正在关注地理围栏教程:https://www.raywenderlich.com/136165/core-location-geofencing-tutorial

由于即使关闭应用程序也会监视用户位置,因此触发事件时,应使用AppDelegate来处理事件,因为尚未加载视图控制器。

在处理事件的AppDelegate中,如果应用程序处于活动状态,我想弹出警报让用户选择停止监视位置。停止位置监视的功能(myFunction)位于视图控制器中。

3 个答案:

答案 0 :(得分:3)

如果它的根很容易:

(window.rootViewController as? ViewController)?.myFunction()

如果它位于navigationController

之上
((window.rootViewController as? UINavigationController)?.topViewController as? ViewController)?.myFunction()

但在任何一种情况下,它都很奇怪,可能不是正确的事情。改为使用NotificationCenter并在AppDelegate中发布通知名称,然后让ViewController监听消息并做出相应的响应。

答案 1 :(得分:0)

您不应该从appdelegate调用视图控制器方法。这是一种不好的做法,通常不是必需的。 如果您想对以下方法做出反应: willResignActive willTerminate

您应该使用NotificationCenter收听有关这些事件的通知。

答案 2 :(得分:0)

发送通知听起来更干净。但要做OP正在尝试的事情,虽然不干净,我曾经在早期的Xcode日做这件事,我完成时没有任何问题。

假设你想从AppDelegate.m调用myViewCtlr中的myMethod

App Delegate中的

执行此操作

//In AppDelegate.h define
...
UIViewController *cur_ViewCtrl
... 
@property (nonatomic, retain) UIViewController *cur_ViewCtrlr;


// in the AppDelegate.m you can call the method like this:

@synthetize cur_ViewCtrlr;
... 
if([cur_ViewCtrlr isKindOfClass:[myViewCtlr class]])
       [(myViewCtlr*) cur_ViewCtrlr myMethod:arg];
...    

然后你只需将指针设置为当前控制器,为简单起见我放在ViewDidLoad上你可能必须在ViewWillAppear中这样做,如果你是通过差异屏幕翻转,但想法是相同的

// In myViewController
...
- (void)viewDidLoad
{
  ...
  AppDelegate *My_delegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
  //and set the reference to this conrtoller in the appDelegate
  My_delegate.cur_ViewCtrlr = self; 
...