我有一个视图控制器,其中我的值为 0(标签),当我从另一个视图控制器打开该视图控制器时,ViewController
我已将viewDidAppear
标签上的值设置为 20。它工作正常,但是当我关闭我的应用程序并再次打开我的应用程序但值没有改变,因为viewDidLoad
,viewDidAppear
并且viewWillAppear
没有被调用。打开我的应用程序时如何拨打电话。我必须做任何事情applicationDidBecomeActive
吗?
8 回答
对事件的确切顺序感到好奇,我按如下方式检测了一个应用程序:(@Zohaib,您可以使用下面的 NSNotificationCenter 代码来回答您的问题)。
// AppDelegate.m
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(@"app will enter foreground");
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSLog(@"app did become active");
}
// ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"view did load");
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
- (void)appDidBecomeActive:(NSNotification *)notification {
NSLog(@"did become active notification");
}
- (void)appWillEnterForeground:(NSNotification *)notification {
NSLog(@"will enter foreground notification");
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"view will appear");
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"view did appear");
}
启动时,输出如下所示:
2013-04-07 09:31:06.505 myapp[15459:11303] view did load
2013-04-07 09:31:06.507 myapp[15459:11303] view will appear
2013-04-07 09:31:06.511 myapp[15459:11303] app did become active
2013-04-07 09:31:06.512 myapp[15459:11303] did become active notification
2013-04-07 09:31:06.517 myapp[15459:11303] view did appear
进入后台,然后重新进入前台:
2013-04-07 09:32:05.923 myapp[15459:11303] app will enter foreground
2013-04-07 09:32:05.924 myapp[15459:11303] will enter foreground notification
2013-04-07 09:32:05.925 myapp[15459:11303] app did become active
2013-04-07 09:32:05.926 myapp[15459:11303] did become active notification
使用 Objective-C
UIApplicationWillEnterForegroundNotification
您应该在您ViewController
的方法中注册 a ,viewDidLoad
并且每当应用程序从后台返回时,您都可以在注册通知的方法中执行您想做的任何事情。ViewController
的viewWillAppear或viewDidAppear当应用程序从后台返回到前台时不会被调用。
-(void)viewDidLoad{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doYourStuff)
name:UIApplicationWillEnterForegroundNotification object:nil];
}
-(void)doYourStuff{
// do whatever you want to do when app comes back from background.
}
不要忘记取消注册您注册的通知。
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
请注意,如果您注册您viewController
的,UIApplicationDidBecomeActiveNotification
那么每次您的应用程序激活时都会调用您的方法,不建议注册viewController
此通知。
使用斯威夫特
要添加观察者,您可以使用以下代码
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: "doYourStuff", name: UIApplication.willEnterForegroundNotification, object: nil)
}
func doYourStuff(){
// your code
}
要删除观察者,您可以使用 swift 的 deinit 函数。
deinit {
NotificationCenter.default.removeObserver(self)
}
斯威夫特 3.0++ 版本
在您的viewDidLoad
,在通知中心注册以收听从后台打开的操作
NotificationCenter.default.addObserver(self, selector:#selector(doSomething), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
然后添加此功能并执行所需的操作
func doSomething(){
//...
}
最后添加这个函数来在你的视图控制器被销毁时清理通知观察者。
deinit {
NotificationCenter.default.removeObserver(self)
}
斯威夫特 4.2。版本
注册 NotificationCenterviewDidLoad
以在应用从后台返回时收到通知
NotificationCenter.default.addObserver(self, selector: #selector(doSomething), name: UIApplication.willEnterForegroundNotification, object: nil)
实现应该调用的方法。
@objc private func doSomething() {
// Do whatever you want, for example update your view.
}
ViewController
一旦被销毁,您可以删除观察者。仅在 iOS9 和 macOS 10.11 以下需要
deinit {
NotificationCenter.default.removeObserver(self)
}
只需让您的视图控制器注册UIApplicationWillEnterForegroundNotification
通知并做出相应的反应。
我认为注册 UIApplicationWillEnterForegroundNotification 是有风险的,因为您最终可能会有多个控制器对该通知做出反应。没有任何保证这些控制器在收到通知时仍然可见。
这是我要做的:我直接从应用程序的委托 didBecomeActive 方法强制在活动控制器上调用 viewDidAppear:
将以下代码添加到- (void)applicationDidBecomeActive:(UIApplication *)application
UIViewController *activeController = window.rootViewController;
if ([activeController isKindOfClass:[UINavigationController class]]) {
activeController = [(UINavigationController*)window.rootViewController topViewController];
}
[activeController viewDidAppear:NO];
尝试在 AppDelegate applicationWillEnterForeground 中添加它。
func applicationWillEnterForeground(_ application: UIApplication) {
// makes viewWillAppear run
self.window?.rootViewController?.beginAppearanceTransition(true, animated: false)
self.window?.rootViewController?.endAppearanceTransition()
}
根据 Apple 的文档:
(void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated;
描述:
告诉子控制器它的外观即将改变。如果您正在实现自定义容器控制器,请使用此方法告诉孩子它的视图即将出现或消失。不要直接调用viewWillAppear:
, viewWillDisappear:
, viewDidAppear:
, 或viewDidDisappear:
。
(void)endAppearanceTransition;
描述:
告诉子控制器其外观已更改。如果您正在实现自定义容器控制器,请使用此方法告诉孩子视图转换已完成。
示例代码:
(void)applicationDidEnterBackground:(UIApplication *)application
{
[self.window.rootViewController beginAppearanceTransition: NO animated: NO]; // I commented this line
[self.window.rootViewController endAppearanceTransition]; // I commented this line
}
问题:我是如何解决的?
Ans : 我在应用程序中发现了这条线。这些行使我的应用程序没有收到任何 ViewWillAppear 通知。当我评论这些行时,它工作正常。