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.
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.
The methods ViewDidAppear and ViewWillAppear as they sound to you, called every time the view Appear on the screen. thanks for helping me.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With