viewWillEnterForeground issue - swift

xcode10.1
swift4.2
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(self.viewWillEnterForeground(_:)), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
}
I used to use code above to run method when the app enter foreground. However, this code does not run anymore. There is no UIApplicationWillEnterForeground after NSNotification.Name.
Anyone knows how to add notification method when the app enter foreground in VC?

Add notification observer in viewDidLoad of the view controller
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(self.viewWillEnterForeground(_:)), name: UIApplication.willEnterForegroundNotification, object: nil)
}
#objc func viewWillEnterForeground(_ notification: Notification) {
//Work anything app enter in background
}
The post-notification fire from app delegate willEnterForgroundMethod
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
NotificationCenter.default.post(name: UIApplication.willEnterForegroundNotification, object: nil)
}

Related

App crashing when adding completion to the observer

I'm trying to add a block to the notification observer, but the app is getting crashed when moving foreground and background. If I'm adding method to observer its working fine, only in case of block its getting crashed. Here is my code which I'm trying for the same.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(foregroundEntered(closure:)), name: UIApplication.willEnterForegroundNotification, object: nil)
// Do any additional setup after loading the view.
}
#objc func foregroundEntered(closure: () -> Void) {
/// do some stuff
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
}
}
Thanks in advance.
Replace
#objc func foregroundEntered(closure: () -> Void) {
With
#objc func foregroundEntered(_ notif: NSNotification) {
And change
NotificationCenter.default.addObserver(self, selector: #selector(foregroundEntered), name: UIApplication.willEnterForegroundNotification, object: nil)

How to move StatView programmatically when keyboard shows

I have a login page which has two textviews and a button in a stackView
I'm trying to move the stackview when the keyboard shows and also disappears as I want to know how to do this programmatically
iOS sends 2 notifications when keyboard will show/hide
UIKeyboardWillShow
UIKeyboardWillHide
What you can do, is observe those notifications, and move the frame of your stackView such as
#objc func keyboardWillShow() {
if stackView.frame.origin.y == 0 {
stackView.frame.origin.y -= 200
}
}
#objc func keyboardWillHide() {
if stackView.frame.origin.y != 0 {
stackView.frame.origin.y = 0
}
}
And here is how to observe those notification. (use this code in your viewDidLoad function)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: Notification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: Notification.Name.UIKeyboardWillHide, object: nil)
Swift 4.2
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIWindow.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: UIWindow.keyboardWillHideNotification, object: nil)
}
#objc func keyboardWillShow(notification: NSNotification) {
print("keyboardWillShow")
}
#objc func keyboardWillHide(notification: NSNotification){
print("keyboardWillHide")
}
If still got any error check below link:
LINK FOR KEYBOARD HIDE/SHOW

Subviews does not follow constraints and dismissing keyboard leaves a black space at the bottom of the view

Whenever my root view controller(Navigation Controller) pushes to my 2nd VC (let's call it VC2), all of VC2's subviews: buttons, labels, and text fields get shifted down even though I've set constraints on it. Also, whenever I dismiss the keyboard after editing the text field, the view goes back to its intended place where the constraints set it to be and leaves a black space at the bottom of the view. Here is my code for VC2:
override func viewDidLoad() {
super.viewDidLoad()
view.layer.backgroundColor = UIColor(named: const.white)?.cgColor
nameField.delegate = self
emailField.delegate = self
passField.delegate = self
setUpTitles()
setUpTextFields()
setUpButton()
addPaddingAndBorder(to: nameField)
addPaddingAndBorder(to: emailField)
addPaddingAndBorder(to: passField)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeView(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardIsDone(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeView(notification:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard(_:)))
self.view.addGestureRecognizer(tap)
}
deinit {
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
#objc func keyboardWillChangeView(notification: Notification){
view.frame.origin.y = -150 //This is temporary
}
#objc func keyboardIsDone(notification: Notification){
view.frame.origin.y = 0
}
#objc func dismissKeyboard(_: UITapGestureRecognizer){ //Tapping outside the keyboard
nameField.resignFirstResponder()
emailField.resignFirstResponder()
passField.resignFirstResponder()
}
//Executed when hitting return key
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
nameField.resignFirstResponder()
emailField.resignFirstResponder()
passField.resignFirstResponder()
view.frame.origin.y = 0
return true
}
Before:
After:
When you use responders you should make your first textfield to be a first responder, like that:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
firstTextField.becomeFirstResponder()
}
This is my answer in different issue

How to run code in your main view controller in swift when a pop up closes

I'm currently writing my first swift app. Currently there is one view/view controller that loads when the app is run as well as a popup window tied to a separate view-controller (like so: https://www.youtube.com/watch?v=S5i8n_bqblE). When I close the pop-up I want to update several things on my original view and run some code. However, neither func viewDidLoad() nor func viewDidAppear() seems to run. And I can't do anything from the pop-up view since I don't have access to the components in the main view-controller from it. What should I do?
The pop-up is "presented modally" if that makes a difference?
I'm assuming you have a MainViewController from which you're presenting the PopupVC. You can use delegate pattern here.
Define a PopupVCDelegate as follow
protocol PopupVCDelegate {
func popupDidDisappear()
}
In your PopupVC define a delegate property of type PopupVCDelegate. And in the closePopup method, call the delegate method popupDidDisappear
class PopupVC: UIViewController {
public var delegate: PopupVCDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func closePopup(_ sender: Any) {
dismiss(animated: true, completion: nil)
delegate?.popupDidDisappear()
}
}
Now any class that adopts this delegate will be able to receive the callback when the closePopup is called. So make your MainViewController to adopt this delegate.
class MainViewController: UIViewController, PopupVCDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
func showPopup() {
let popupViewController = //Instantiate your popup view controller
popupViewController.delegate = self
//present your popup
}
func popupDidDisappear() {
//This method will be called when the popup is closed
}
}
Another way is to fire a notification through NSNotificationCenter on closePopup and add an observer in MainViewController to listen to that notification. But it is not recommended in this scenario.
Edit
As you have asked for the NSNotificationCenter method. Please change your classes as follow
class PopupVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func closePopup(_ sender: Any) {
dismiss(animated: true, completion: nil)
NotificationCenter.default.post(name: NSNotification.Name("notificationClosedPopup"), object: nil)
}
}
class MainViewController: UIViewController, PopupVCDelegate {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(onPopupClosed), name: NSNotification.Name(rawValue: "notificationClosedPopup"), object: nil)
}
#objc func onPopupClosed() {
//This method will be called when the popup is closed
}
deinit {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "notificationClosedPopup"), object: nil)
}
}

Communication between main app and today extension by swift

is possiblity when i put a data by UserDefaults in main app, and call the extension func in a time?
i find an other way in here
How to send and receive data in Today extensions
but it's not working, the following is my code
main app
#IBOutlet weak var nextButton: UIButton! {
didSet {
nextButton.addTarget(self, action: #selector(selectNextButton), for: UIControlEvents.touchUpInside)
}
}
func selectNextButton() {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "SpecialKey"), object: nil, userInfo: ["MyData": 10])
}
today extension
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(dataReceived(notification:)), name: NSNotification.Name(rawValue: "SpecialKey"), object: nil)
}
func dataReceived(notification: NSNotification) {
print("Received Data")
}