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

发布于 2024-09-18 04:43:43 字数 219 浏览 12 评论 0原文

我的主 AppDelegate.m 类中有 UIApplicationDelegate 协议,并定义了 applicationDidBecomeActive 方法。

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

I have the UIApplicationDelegate protocol in my main AppDelegate.m class, with the applicationDidBecomeActive method defined.

I want to call a method when the application returns from the background, but the method is in another view controller. How can I check which view controller is currently showing in the applicationDidBecomeActive method and then make a call to a method within that controller?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

此岸叶落 2024-09-25 04:43:43

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

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

不要忘记自己清理干净!当您的视图消失时,请记住将自己从观察者中删除:

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

有关 通知中心

Any class in your application can become an "observer" for different notifications in the application. When you create (or load) your view controller, you'll want to register it as an observer for the UIApplicationDidBecomeActiveNotification and specify which method that you want to call when that notification gets sent to your application.

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

Don't forget to clean up after yourself! Remember to remove yourself as the observer when your view is going away:

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

More information about the Notification Center.

許願樹丅啲祈禱 2024-09-25 04:43:43

Swift 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
}

Swift 3, 4 Equivalent:

adding observer

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

removing observer

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

callback

@objc func applicationDidBecomeActive() {
    // handle event
}
醉生梦死 2024-09-25 04:43:43

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.
}

Swift 2 Equivalent:

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.
}
两仪 2024-09-25 04:43:43

斯威夫特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
    }

Swift 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
    }
马蹄踏│碎落叶 2024-09-25 04:43:43

Swift 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() {
}

Swift 4.2

Add observer-

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

Remove observer-

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

Handle Event-

@objc func handleEvent() {
}
心清如水 2024-09-25 04:43:43

在 Swift 4 中,Apple 通过新的编译器警告建议我们避免在这种情况下使用 #selector。以下是实现此目的的更安全的方法:

首先,创建一个将保存观察者实例的变量(将用于取消它):

var didBecomeActiveObserver: NSObjectProtocol

然后创建一个可由通知使用的惰性变量:

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

如果您需要实际的要包含通知,只需将 _ 替换为 notification 即可。

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

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

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

最后,我们移除观察者。

func removeObserver() {
    NotificationCenter.default.removeObserver(didBecomeActiveObserver)
}

With Swift 4, Apple advises via a new compiler warning that we avoid the use of #selector in this scenario. The following is a much safer way to accomplish this:

First, create a variable that will hold the observer instance (that will be used to cancel it):

var didBecomeActiveObserver: NSObjectProtocol

Then create a lazy var that can be used by the notification:

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

If you require the actual notification be included, just replace the _ with notification.

Next, we set up the notification to observe for the app becoming active.

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

The big change here is that instead of calling a #selector, we now call the var created above. This can eliminate situations where you get invalid selector crashes.

Finally, we remove the observer.

func removeObserver() {
    NotificationCenter.default.removeObserver(didBecomeActiveObserver)
}
爱格式化 2024-09-25 04:43:43

组合方式:

import Combine

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

The Combine way:

import Combine

var cancellables = Set<AnyCancellable>()
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
    .sink { notification in
            // do stuff
    }.store(in: &cancellables)
柳絮泡泡 2024-09-25 04:43:43

Swift 5 版本:

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

不再需要删除观察者< /a> 在 iOS 9 及更高版本中。

Swift 5 version:

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

Removing the observer is no longer required in iOS 9 and later.

陌路黄昏 2024-09-25 04:43:43

在 Swift 5 中

override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)

         NotificationCenter.default.addObserver(self, selector: #selector(applicationWillResignActive), name: UIApplication.willResignActiveNotification, object: nil)
    
         NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
        }
    
    override func viewWillDisappear(_ animated: Bool) { 
        super.viewWillDisappear(animated)

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

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


@objc private func applicationWillResignActive() {
    }

    @objc private func applicationDidBecomeActive() {
    }

In Swift 5

override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)

         NotificationCenter.default.addObserver(self, selector: #selector(applicationWillResignActive), name: UIApplication.willResignActiveNotification, object: nil)
    
         NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
        }
    
    override func viewWillDisappear(_ animated: Bool) { 
        super.viewWillDisappear(animated)

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

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


@objc private func applicationWillResignActive() {
    }

    @objc private func applicationDidBecomeActive() {
    }
且行且努力 2024-09-25 04:43:43

如果你们中有人使用 SwiftUI:

.onReceive(NotificationCenter.default.publisher(
    for: UIApplication.didBecomeActiveNotification)) { _ in
        print("DID BECOME ACTIVE")
    }
)

If any of you is using SwiftUI:

.onReceive(NotificationCenter.default.publisher(
    for: UIApplication.didBecomeActiveNotification)) { _ in
        print("DID BECOME ACTIVE")
    }
)
客…行舟 2024-09-25 04:43:43

更清洁的 Swift 5+ 解决方案

将观察者添加到 initviewDidLoad 中:

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

您不需要像其他答案所建议的那样删除观察者。 它将自动完成

@objc private func appDidBecomeActive() {
    // do your magic
}

Cleaner Swift 5+ solution

Add the observer to init or viewDidLoad:

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

You don't need to remove the observer as other answers suggest. It will be done automatically.

@objc private func appDidBecomeActive() {
    // do your magic
}
猫七 2024-09-25 04:43:43

对于 Swift5 MacOS,您需要使用 NSApplication 而不是 UIApplication。

NotificationCenter.default.addObserver(self,
                                       selector: #selector(applicationDidBecomeActive),
                                       name: (NSApplication.didBecomeActiveNotification),
                                       object: nil)
    }

For Swift5 MacOS, you need to use NSApplication instead of UIApplication.

NotificationCenter.default.addObserver(self,
                                       selector: #selector(applicationDidBecomeActive),
                                       name: (NSApplication.didBecomeActiveNotification),
                                       object: nil)
    }
撧情箌佬 2024-09-25 04:43:43

在 SwiftUI 中我们可以使用 ScenePhase 来观察这些变化。例如

import SwiftUI

struct DetailView: View {
    @Environment(\.scenePhase) private var scenePhase
    var body: some View {
        VStack {
            Text("Hello welcome to swiftui")
        }
        .onChange(of: scenePhase) { newValue in
            if newValue == .active {
                print("DetailView scene updated to active state")
            }
            if newValue == .inactive {
                print("DetailView scene updated to inactive state")
            }
            if newValue == .background {
                print("DetailView scene updated to background state")
            }
        }
    }
}

,现在,一旦您将应用程序置于后台,则将发生以下事件 --

DetailView scene updated to inactive state
DetailView scene updated to background state

现在,一旦将应用程序置于前台,则将发生以下事件 --

DetailView scene updated to inactive state
DetailView scene updated to active state

您可以使用从 访问此 scenePhase 环境对象WindowsGroupScene 和任何View

ScenePhase 符合 Comparable 并有以下情况 -

    /// The scene isn't currently visible in the UI.
    ///
    /// Do as little as possible in a scene that's in the `background` phase.
    /// The `background` phase can precede termination, so do any cleanup work
    /// immediately upon entering this state. For example, close any open files
    /// and network connections. However, a scene can also return to the
    /// ``ScenePhase/active`` phase from the background.
    ///
    /// Expect an app that enters the `background` phase to terminate.
    case background

    /// The scene is in the foreground but should pause its work.
    ///
    /// A scene in this phase doesn't receive events and should pause
    /// timers and free any unnecessary resources. The scene might be completely
    /// hidden in the user interface or otherwise unavailable to the user.
    /// In macOS, scenes only pass through this phase temporarily on their way
    /// to the ``ScenePhase/background`` phase.
    ///
    /// An app or custom scene in this phase contains no scene instances in the
    /// ``ScenePhase/active`` phase.
    case inactive

    /// The scene is in the foreground and interactive.
    ///
    /// An active scene isn't necessarily front-most. For example, a macOS
    /// window might be active even if it doesn't currently have focus.
    /// Nevertheless, all scenes should operate normally in this phase.
    ///
    /// An app or custom scene in this phase contains at least one active scene
    /// instance.
    case active

In SwiftUI we can use the ScenePhase to observe these changes. e.g

import SwiftUI

struct DetailView: View {
    @Environment(\.scenePhase) private var scenePhase
    var body: some View {
        VStack {
            Text("Hello welcome to swiftui")
        }
        .onChange(of: scenePhase) { newValue in
            if newValue == .active {
                print("DetailView scene updated to active state")
            }
            if newValue == .inactive {
                print("DetailView scene updated to inactive state")
            }
            if newValue == .background {
                print("DetailView scene updated to background state")
            }
        }
    }
}

Now once you put you application to background then following events will happen --

DetailView scene updated to inactive state
DetailView scene updated to background state

Now once you put you application to foreground then following events will happen --

DetailView scene updated to inactive state
DetailView scene updated to active state

You can use access this scenePhase environment object from WindowsGroup, Scene and from any View.

ScenePhase conforms to Comparable and have the following cases -

    /// The scene isn't currently visible in the UI.
    ///
    /// Do as little as possible in a scene that's in the `background` phase.
    /// The `background` phase can precede termination, so do any cleanup work
    /// immediately upon entering this state. For example, close any open files
    /// and network connections. However, a scene can also return to the
    /// ``ScenePhase/active`` phase from the background.
    ///
    /// Expect an app that enters the `background` phase to terminate.
    case background

    /// The scene is in the foreground but should pause its work.
    ///
    /// A scene in this phase doesn't receive events and should pause
    /// timers and free any unnecessary resources. The scene might be completely
    /// hidden in the user interface or otherwise unavailable to the user.
    /// In macOS, scenes only pass through this phase temporarily on their way
    /// to the ``ScenePhase/background`` phase.
    ///
    /// An app or custom scene in this phase contains no scene instances in the
    /// ``ScenePhase/active`` phase.
    case inactive

    /// The scene is in the foreground and interactive.
    ///
    /// An active scene isn't necessarily front-most. For example, a macOS
    /// window might be active even if it doesn't currently have focus.
    /// Nevertheless, all scenes should operate normally in this phase.
    ///
    /// An app or custom scene in this phase contains at least one active scene
    /// instance.
    case active
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文