Skip to content

Instantly share code, notes, and snippets.

@KentarouKanno
Last active July 17, 2017 01:47
Show Gist options
  • Save KentarouKanno/bbe67154775f0dbd698f to your computer and use it in GitHub Desktop.
Save KentarouKanno/bbe67154775f0dbd698f to your computer and use it in GitHub Desktop.
NSNotificationCenter

NSNotificationCenter

★ Notification Nameを定義する

// Notification Name
extension Notification.Name {
    static let textFieldFocus = Notification.Name("textFieldFocus")
}

// テキストフィールドにフォーカスが入った時の通知
notificationCenter.addObserver(self, selector: #selector(self.textFieldFocusNotification(notification:)),
                               name: NSNotification.Name.textFieldFocus,
                               object: nil)


func textFieldFocusNotification(notification: Notification) {
    
}

★ 通知をクロージャーで実行

var notify: NSObjectProtocol!

// 実行するスレッドも指定可能
notify = NSNotificationCenter.defaultCenter().addObserverForName("NotificationName", object: nil, queue: NSOperationQueue.mainQueue()) { (notify) -> Void in
    print("Notification call")
}

// 通知名を指定して通知を送信する
NSNotificationCenter.defaultCenter().postNotificationName("NotificationName", object: nil)

// 通知の登録先を指定しない為、返り値のオブジェクトを保持して削除する
NSNotificationCenter.defaultCenter().removeObserver(notify)

★ NSObjectを継承していないクラスで通知を受ける

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.callMethod()), name: "NotificationName", object: nil)

// @objcを付ける
@objc
func callMethod(notification: NSNotification) {

}

★ object,UserInfoを渡すサンプル

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 通知を登録
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.setLabel1(_:)), name: "Notification1", object: nil)
}

deinit {
    // 通知を解除
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

func setLabel1(notification: NSNotification) {
    
    print(notification.object)
    print(notification.userInfo)
    /*
    Optional(ABC)
    Optional([key1: abc, key2: 1])
    */
    
    if let value = notification.userInfo!["str"] as? String {
        label.text = value
    }
}

// 通知を送信
NSNotificationCenter.defaultCenter().postNotificationName("Notification1", object: "ABC", userInfo: ["key1": "abc", "key2": 1])

★ NSNotificationオブジェクトを生成し通知を呼びだす

// 通知を登録する
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("callMethod"), name: "NotificationName", object: nil)


// NSNotificationオブジェクトを生成
let notification = NSNotification(name: "NotificationName", object: nil, userInfo: ["key": "value"])

// 通知を呼び出す
NSNotificationCenter.defaultCenter().postNotification(notification)

★ 通知を登録、解除、送信、データ取得(userInfo)

override func viewDidLoad() {
    super.viewDidLoad()
    // 通知を登録する
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.callMethod(_:)), name: "NotificationName", object: nil)
}

deinit {
    // 通知を解除
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

// 通知に値を添付して送信する
// userInfoに[NSObject : AnyObject]?型のDictionaryを渡す

let dict = ["number": 100, "string": "abc"];
NSNotificationCenter.defaultCenter().postNotificationName("NotificationName", object: nil, userInfo: dict)


// 通知に添付されている値を取り出す
func callMethod(notification: NSNotification) {
    if let userInfo = notification.userInfo?["number"] where userInfo is Int {
        var value = userInfo as! Int
        value += 10
        //=> 110
    }
  
    if let userInfo = notification.userInfo?["string"] where userInfo is String {
        var value = userInfo as! String
        value += "def"
        //=> abcdef
    }
}

★ 通知を登録、解除、送信、データ取得(object)

override func viewDidLoad() {
    super.viewDidLoad()
    // 通知を登録
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.callMethod(_:)), name: "NotificationName", object: nil)
}

deinit {
    // 通知を解除
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

// 通知を送信
NSNotificationCenter.defaultCenter().postNotificationName("NotificationName", object: "Sample")

// 通知からデータを取得(object)
func callMethod(notification: NSNotification)  {
    print(notification.object as! String)
    //=> "Sample"
}

★ Keyboardが表示される直前に呼ばれる通知を登録

// キーボードが表示される直前の通知
notificationCenter.addObserver(self, selector: #selector(self.willShowKeyboard(notification:)),
                               name: NSNotification.Name.UIKeyboardWillShow,
                               object: nil)

func willShowKeyboard(notification: Notification) {
    
    if let userInfo = (notification as NSNotification).userInfo,
        let keyBoardRect = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
        let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? TimeInterval {
        
        keyBoardRect
        //=> (0.0, 451.0, 375.0, 216.0)
        
        duration
        //=> 0.25
    }
}

★ UIApplication Notification Name

UIApplicationDidEnterBackgroundNotification
UIApplicationWillEnterForegroundNotification
UIApplicationDidFinishLaunchingNotification
UIApplicationDidBecomeActiveNotification
UIApplicationWillResignActiveNotification
UIApplicationDidReceiveMemoryWarningNotification
UIApplicationWillTerminateNotification
UIApplicationSignificantTimeChangeNotification
UIApplicationWillChangeStatusBarOrientationNotification
UIApplicationDidChangeStatusBarOrientationNotification
UIApplicationWillChangeStatusBarFrameNotification
UIApplicationDidChangeStatusBarFrameNotification

UIApplicationLaunchOptionsRemoteNotificationKey
UIApplicationLaunchOptionsLocalNotificationKey

// Dictionary key
UIApplicationStatusBarOrientationUserInfoKey
UIApplicationStatusBarFrameUserInfoKey

★ UIWindow Notification Name

UIKeyboardWillShowNotification
UIKeyboardDidShowNotification
UIKeyboardWillHideNotification
UIKeyboardDidHideNotification

@available(iOS 5.0, *)
UIKeyboardWillChangeFrameNotification
UIKeyboardDidChangeFrameNotification

// Dictionary key
UIKeyboardFrameBeginUserInfoKey
UIKeyboardFrameEndUserInfoKey
UIKeyboardAnimationDurationUserInfoKey
UIKeyboardAnimationCurveUserInfoKey

★ ViewControllerで起動時、バックグラウンド遷移時の通知を受け取る

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
       
       NotificationCenter.default.addObserver(self, selector: #selector(self.becomeActive(_:)), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.enterBackground(_:)), name: UIApplicationDidEnterBackgroundNotification , object: nil)
    }
    
    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
    func becomeActive(notification: NSNotification) {
        print("becomeActive")
    }
    
    func enterBackground(notification: NSNotification) {
        print("enterBackground")
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
    }
}

★ キーボード空の入力でからの時にボタンを非活性にする通知の実装

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var barButtonItem: UIBarButtonItem!
    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        barButtonItem.isEnabled = false
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(self.didChangeNotification(notification:)),
            name: NSNotification.Name.UITextFieldTextDidChange,
            object: nil
        )
    }
    
    func didChangeNotification(notification: Notification) {
        if let text = textField.text, !text.isEmpty {
            barButtonItem.isEnabled = true
        } else {
            barButtonItem.isEnabled = false
        }}

    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        view.endEditing(true)
    }
}

★ Keyboardにフォーカスが入った時に画面のBottom Constraintを変更する
Github Sample

import UIKit

class ViewController1: UIViewController {
   
   @IBOutlet weak var baseViewBottomConstraint: NSLayoutConstraint!

   override func viewDidLoad() {
       super.viewDidLoad()

       // Set Notification
       let notificationCenter = NotificationCenter.default
       notificationCenter.addObserver(self, selector: #selector(self.willChangeKeyboard(_:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
       notificationCenter.addObserver(self, selector: #selector(self.willHideKeyboard(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
       notificationCenter.addObserver(self, selector: #selector(self.willChangeKeyboard(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
   }

   deinit {
       NotificationCenter.default.removeObserver(self)
   }
   
   override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
       view.endEditing(true)
   }
   
   // WillChange Keyboad
   func willChangeKeyboard(_ notification: Notification) {
       
       if let userInfo = (notification as NSNotification).userInfo {
           if let keyboard = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue,
               let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? TimeInterval {
               
               let keyBoardHeight = keyboard.cgRectValue.height
               self.baseViewBottomConstraint.constant = keyBoardHeight
               
               UIView.animate(withDuration:duration, animations: {
                   self.view.layoutIfNeeded()
               })
           }
       }
   }
   
   // WillHide Keyboard
   func willHideKeyboard(_ notification: Notification) {
       
       if let userInfo = (notification as NSNotification).userInfo {
           if let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? TimeInterval {
               
               self.baseViewBottomConstraint.constant = 0
               UIView.animate(withDuration:duration, animations: {
                   self.view.layoutIfNeeded()
               }, completion: { finish in
                   
               })
           }
       }
   }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment