翻譯 Swift Tip Notifications

翻譯自 Swift Tip: Notifications · objc.ioswift

Episode 107 Swift Talk 系列文章中 有一篇重構很大的 view controllers,咱們 將代碼從view controller 移動到一個子 view controller。利用生成的子view controller 處理鍵盤通知。安全

在本週的Tips中,咱們將展現如何分解代碼。bash

在多個地方經過通知監聽鍵盤事件,每一個監聽回調的方法中都會手動獲取屬性,好比:ui

@objc func keyboardChanged(notification: NSNotification) {
  guard let userInfo = notification.userInfo,
        let frameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }
  let keyboardScreenFrame = frameValue.cgRectValue
  // …
}
複製代碼

爲了節約時間避免一遍遍寫重複的獲取代碼,咱們能夠寫一個包含全部屬性的結構體I:spa

struct KeyboardInfo {
    var animationCurve: UIView.AnimationCurve
    var animationDuration: Double
    var isLocal: Bool
    var frameBegin: CGRect
    var frameEnd: CGRect
}
複製代碼

如今咱們能夠寫一個初始化方法,在這個方法中根據notification的數據組裝KeyboardInfo結構體:翻譯

extension KeyboardInfo {
    init?(_ notification: Notification) {
        guard notification.name == UIResponder.keyboardWillShowNotification || notification.name == UIResponder.keyboardWillChangeFrameNotification else { return nil }
        let u = notification.userInfo!

        animationCurve = UIView.AnimationCurve(rawValue: u[UIWindow.keyboardAnimationCurveUserInfoKey] as! Int)!
        animationDuration = u[UIWindow.keyboardAnimationDurationUserInfoKey] as! Double
        isLocal = u[UIWindow.keyboardIsLocalUserInfoKey] as! Bool
        frameBegin = u[UIWindow.keyboardFrameBeginUserInfoKey] as! CGRect
        frameEnd = u[UIWindow.keyboardFrameEndUserInfoKey] as! CGRect
    }
}
複製代碼

在咱們的 ::keyboardChanged(notification:):: 方法中, 咱們能夠使用KeyboardInfo結構體,而不是手動解析userInfo字典中的數據:code

@objc func keyboardChanged(notification: NSNotification) {
  guard let payload = KeyboardInfo(notification) else { return }
  let keyboardScreenFrame = payload.frameEnd
  // …
}
複製代碼

這樣寫的代碼更簡潔,並且更安全一些 (如今字段只在一個地方讀取). 當咱們想訪問其餘屬性時, 咱們只須要輸入payload ,而後它會自動將建議的屬性名稱補全.blog

Swift Talk Episode 27 (公開課程), 咱們在這種方式的基礎上,進一步建立了一種類型安全的觀察這。事件

相關文章
相關標籤/搜索