处理applicationDidBecomeActive-“视图控制器如何响应应用程序变为活动状态?”


179

UIApplicationDelegate在主AppDelegate.m类中具有协议,并且applicationDidBecomeActive定义了方法。

当应用程序从后台返回时,我想调用一个方法,但是该方法在另一个视图控制器中。如何检查当前在applicationDidBecomeActive方法中显示的视图控制器,然后在该控制器中调用方法?

Answers:


304

应用程序中的任何类都可以成为应用程序中不同通知的“观察者”。创建(或加载)视图控制器时,您需要将其注册为的观察者,UIApplicationDidBecomeActiveNotification并指定当该通知发送到应用程序时要调用的方法。

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(someMethod:)
                                             name:UIApplicationDidBecomeActiveNotification object:nil];

不要忘了自己清理!当视图消失时,请记住将自己作为观察者:

[[NSNotificationCenter defaultCenter] removeObserver:self 
                                                name:UIApplicationDidBecomeActiveNotification
                                              object:nil];

有关通知中心的更多信息。


优秀的。没想到使用NSNotificationCenter。谢谢!
加尔文(2010年

3
只是该行代码中的错字(缺少“名称”):[[NSNotificationCenter defaultCenter] addObserver:自我选择器:@selector(someMethod :)名称:UIApplicationDidBecomeActiveNotification对象:无]
约翰斯,2010年

3
为了增加Reed的答案,被调用的方法(在本示例中为someMethod)需要接受NSNotification参数。因此someMethod的方法签名为-(void)someMethod:(NSNotification *)notification {//在这里做某事}
Aaron

2
@Aaron可以,但这不是必需的。不过,这是一个很好的见解。谢谢!
Reed Olsen

太棒了!使视图失效/重新创建NSTimer实例的一种好方法,就在视图控制器/其他负责这些NSTimer的对象中。爱它!
idStar 2012年

68

斯威夫特3,4等效:

添加观察者

NotificationCenter.default.addObserver(self,
    selector: #selector(applicationDidBecomeActive),
    name: .UIApplicationDidBecomeActive, // UIApplication.didBecomeActiveNotification for swift 4.2+
    object: nil)

删除观察者

NotificationCenter.default.removeObserver(self,
    name: .UIApplicationDidBecomeActive, // UIApplication.didBecomeActiveNotification for swift 4.2+
    object: nil)

打回来

@objc func applicationDidBecomeActive() {
    // handle event
}

2
我在哪里叫这个?

1
@ user8169082,您可以在需要开始接收通知的任何位置添加观察者。您可以添加它viewDidLoadviewWillAppear:animated为实例。而且,当您不再需要通知时,或者将要在deinit方法中释放观察者实例时,可以删除观察者
igrek

2
迅捷4.2我正在使用:NotificationCenter.default.addObserver(自身,选择器:#selector(applicationDidBecomeActive(notification :)),名称:UIApplication.didBecomeActiveNotification,对象:nil)
Brian

16

Swift 2等效

let notificationCenter = NSNotificationCenter.defaultCenter()

// Add observer:
notificationCenter.addObserver(self,
  selector:Selector("applicationWillResignActiveNotification"),
  name:UIApplicationWillResignActiveNotification,
  object:nil)

// Remove observer:
notificationCenter.removeObserver(self,
  name:UIApplicationWillResignActiveNotification,
  object:nil)

// Remove all observer for all notifications:
notificationCenter.removeObserver(self)

// Callback:
func applicationWillResignActiveNotification() {
  // Handle application will resign notification event.
}

放置removeObserverSwift的最佳位置:deinit方法。
Enrico Susatyo '16

通常,不建议在deinit中访问self。在这一点上,自我处于完全分配和释放之间
Zorayr

1
那你在哪里删除Observer?
Enrico Susatyo '16

2
@EnricoSusatyo,您可以忽略它,因为它是不正确的。覆盖deinit是可以的:“因为直到调用实例后,实例才被释放,所以实例化器可以访问实例的所有属性,并可以基于这些属性修改其行为(例如,查找实例的名称)。需要关闭的文件)。” 打电话给deinit不好
Dan Rosenstark '16

7

斯威夫特4.2

添加观察者-

NotificationCenter.default.addObserver(self, selector: #selector(handleEvent), name: UIApplication.didBecomeActiveNotification, object: nil)

删除观察者-

NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)

处理事件

@objc func handleEvent() {
}

5

对于Swift 4,Apple通过新的编译器警告建议我们避免#selector在这种情况下使用。以下是完成此操作的更安全的方法:

首先,创建一个可以由通知使用的惰性变量:

lazy var didBecomeActive: (Notification) -> Void = { [weak self] _ in
    // Do stuff
} 

如果您需要实际通知被收录,只需更换_notification

接下来,我们设置通知以观察该应用程序是否处于活动状态。

func setupObserver() {
    _ = NotificationCenter.default.addObserver(forName: .UIApplicationDidBecomeActive,
                                               object: nil,
                                               queue:.main,
                                               using: didBecomeActive)
}

这里最大的变化是#selector,我们现在不再调用a ,而是调用上面创建的var。这可以消除出现无效选择器崩溃的情况。

最后,我们删除观察者。

func removeObserver() {
    NotificationCenter.default.removeObserver(self, name: .UIApplicationDidBecomeActive, object: nil)
}

1
#selector可以调用@objc在Swift 4中声明为属性的方法
。– AnBisw

1
它使用不正确,removeObserver(self因为添加观察者时未分配selflet observer = NotificationCenter.default.addObserver然后,您应该removeObserver(observer
Yan Kalbaska '18

感谢@CodeBender我还不知道该功能,并且它(最终)删除了@objc。但是,当我尝试它时,我在控制台中收到警告(Xcode 11.3.1(11C504),Swift 13.3):无法结束BackgroundTask:不存在带有标识符的后台任务。即使将观察者保存为NSObjectProtocol变量。
Palme

没关系,如果我使用@objc变体,我也会收到警告。
金棕榈

3

斯威夫特5

fileprivate  func addObservers() {
      NotificationCenter.default.addObserver(self,
                                             selector: #selector(applicationDidBecomeActive),
                                             name: UIApplication.didBecomeActiveNotification,
                                             object: nil)
    }

fileprivate  func removeObservers() {
        NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
    }

@objc fileprivate func applicationDidBecomeActive() {
// here do your work
    }

0

合并方式:

import Combine

var cancellables = Set<AnyCancellable>()
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
    .sink { notification in
            // do stuff
    }.store(in: &cancellables)
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.