为了账号安全,请及时绑定邮箱和手机立即绑定

为什么当应用程序从后台返回时,不会调用viewWillAppear?

为什么当应用程序从后台返回时,不会调用viewWillAppear?

慕娘9325324 2019-08-24 14:56:01
为什么当应用程序从后台返回时,不会调用viewWillAppear?我正在编写一个应用程序,如果用户在通话时查看应用程序,我需要更改视图。我已经实现了以下方法:- (void)viewWillAppear:(BOOL)animated {     [super viewWillAppear:animated];     NSLog(@"viewWillAppear:");     _sv.frame = CGRectMake(0.0, 0.0, 320.0, self.view.bounds.size.height);}但是,当应用程序返回到前台时,它不会被调用。我知道我可以实现:[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];但我不想这样做。我宁愿将所有布局信息放在viewWillAppear:方法中,让它处理所有可能的场景。我甚至试图从applicationWillEnterForeground:调用viewWillAppear:但我似乎无法确定当前哪个是当前的视图控制器。有人知道处理这个问题的正确方法吗?我确定我错过了一个明显的解决方案。
查看完整描述

3 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞

该方法viewWillAppear应该在您自己的应用程序中发生的事情的上下文中进行,而不是在您从另一个应用程序切换回应用程序时将应用程序置于前台的上下文中。


换句话说,如果有人查看另一个应用程序或接听电话,然后切换回您之前在后台运行的应用程序,您的UIViewController在您离开应用程序时已经可见“不关心”可以这么说 - 就它而言,它永远不会消失,而且它仍然可见 - 因此viewWillAppear不被称为。


我建议不要打电话给viewWillAppear自己 - 它有一个特定的含义,你不应该颠覆!您可以通过重构来实现相同的效果,如下所示:


- (void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];

    [self doMyLayoutStuff:self];

}


- (void)doMyLayoutStuff:(id)sender {

    // stuff

}

然后你也doMyLayoutStuff从相应的通知中触发:


[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doMyLayoutStuff:) name:UIApplicationDidChangeStatusBarFrameNotification object:self];

顺便说一下,没有开箱即用的方法来判断哪个是'当前'的UIViewController。但你可以找到解决方法,例如UINavigationController的委托方法,用于找出何时在其中呈现UIViewController。您可以使用这样的东西来跟踪已经呈现的最新UIViewController。


更新


如果您在各个位上使用适当的自动调整掩码布局UI,有时您甚至不需要处理UI中的“手动” - 它只是处理...


查看完整回答
反对 回复 2019-08-24
?
慕桂英546537

TA贡献1848条经验 获得超10个赞

迅速

简短的回答

使用NotificationCenter观察者而不是viewWillAppear

override func viewDidLoad() {
    super.viewDidLoad()

    // set observer for UIApplication.willEnterForegroundNotification
    NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)}// my selector that was defined above@objc func willEnterForeground() {
    // do stuff}

答案很长

要了解应用程序何时从后台返回,请使用NotificationCenter观察者而不是viewWillAppear。这是一个示例项目,显示何时发生的事件。(这是对Objective-C答案的改编。)

import UIKitclass ViewController: UIViewController {

    // MARK: - Overrides

    override func viewDidLoad() {
        super.viewDidLoad()
        print("view did load")

        // add notification observers
        NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)

    }

    override func viewWillAppear(_ animated: Bool) {
        print("view will appear")
    }

    override func viewDidAppear(_ animated: Bool) {
        print("view did appear")
    }

    // MARK: - Notification oberserver methods

    @objc func didBecomeActive() {
        print("did become active")
    }

    @objc func willEnterForeground() {
        print("will enter foreground")
    }}

首次启动应用程序时,输出顺序为:

view did load
view will appear
did become active
view did appear

按下主页按钮然后将应用程序带回前台后,输出顺序为:

will enter foreground
did become active

因此,如果您最初尝试使用viewWillAppear那么UIApplication.willEnterForegroundNotification可能就是您想要的。

注意

从iOS 9及更高版本开始,您无需删除观察者。该文件规定:

如果您的应用面向iOS 9.0及更高版本或macOS 10.11及更高版本,则无需在其dealloc方法中取消注册观察者。


查看完整回答
反对 回复 2019-08-24
  • 3 回答
  • 0 关注
  • 1939 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信