Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does viewWillAppear not get called when an app comes back from the background?

I'm writing an app and I need to change the view if the user is looking at the app while talking on the phone.

I've implemented the following method:

- (void)viewWillAppear:(BOOL)animated {     [super viewWillAppear:animated];     NSLog(@"viewWillAppear:");     _sv.frame = CGRectMake(0.0, 0.0, 320.0, self.view.bounds.size.height); } 

But it's not being called when the app returns to the foreground.

I know that I can implement:

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

but I don't want to do this. I'd much rather put all my layout information in the viewWillAppear: method, and let that handle all possible scenarios.

I've even tried to call viewWillAppear: from applicationWillEnterForeground:, but I can't seem to pinpoint which is the current view controller at that point.

Does anybody know the proper way to deal with this? I'm sure I'm missing an obvious solution.

like image 328
Philip Walton Avatar asked Mar 11 '11 20:03

Philip Walton


People also ask

What triggers viewWillAppear?

The method viewWillAppear: is triggered in response to a change in the state of the application, indicating that the view controller is becoming “active.” The reason viewDidLoad exists – the only reason – is that it sometimes isn't possible or efficient to configure 100% of an interface in a XIB.

How many times is viewWillAppear called?

The methods ViewDidAppear and ViewWillAppear as they sound to you, called every time the view Appear on the screen. thanks for helping me.

Is viewWillAppear called before viewDidLoad?

viewWillAppear(_:)Always called after viewDidLoad (for obvious reasons, if you think about it), and just before the view appears on the screen to the user, viewWillAppear is called.

What is the difference between viewDidLoad and viewWillAppear?

viewDidLoad ONLY gets called when the view is constructed - so for example after a view controller initFromNibNamed call when the view is accessed. viewWillAppear is called anytime your view controller was not in view but comes into view - so when your view controller is pushed, viewWillAppear is called.


1 Answers

Swift

Short answer

Use a NotificationCenter observer rather than 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 } 

Long answer

To find out when an app comes back from the background, use a NotificationCenter observer rather than viewWillAppear. Here is a sample project that shows which events happen when. (This is an adaptation of this Objective-C answer.)

import UIKit class 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")     }  } 

On first starting the app, the output order is:

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

After pushing the home button and then bringing the app back to the foreground, the output order is:

will enter foreground did become active  

So if you were originally trying to use viewWillAppear then UIApplication.willEnterForegroundNotification is probably what you want.

Note

As of iOS 9 and later, you don't need to remove the observer. The documentation states:

If your app targets iOS 9.0 and later or macOS 10.11 and later, you don't need to unregister an observer in its dealloc method.

like image 87
Suragch Avatar answered Oct 23 '22 14:10

Suragch