iOS 10 的一个重要更新-自定义的通知界面
續上篇,在簡單鬧鐘的例子上,在通知界面上顯示圖片動畫,并用通知關聯的按鈕更新通知界面。介紹 iOS 10 通知 API 的擴展:自定義通知顯示界面。
?
新框架可以統一處理本地通知和遠程推送,同時增加了一些新 API 來控制等待中和已發出的通知。
?
以上這些都很棒,不過蘋果還在通知方面更進一步,讓開發者能添加一個自定義的通知界面,用戶收到通知之后可以選擇查看這個自定義界面。要實現這個功能,需要添加一個單獨的 UserNotificationsUI 框架。這個框架的 API 特別簡單,只含有一個公共的 protocol:UNNotificationContentExtension (https://developer.apple.com/reference/usernotificationsui/unnotificationcontentextension)。
?
工程
?
我們的樣例工程是在上一篇文章的鬧鐘 app 基礎上,增加了一個炫酷的自定義通知界面。通過這個界面,用戶可以不用切換到鬧鐘 app 就能直接取消通知。先來看下效果:
自定義通知界面效果
?
跟所有 Day by Day 系列文章一樣,工程源碼放在了 Github 上。
?
創建 Extension
?
iOS 10 的許多旗艦功能都是建立在蘋果的 Extension 架構上的。前面的系列文章 Xcode 插件 和 iMessage 插件 都是如此。而自定義通知界面也是用同樣的方法實現的。
?
首先,我們要給鬧鐘 app 的工程加一個新的 target。在下面這個選擇 target 模板的界面,選擇 Notification Content。然后隨便起個名字,我用的是 NagMeContentExtension。
?
選擇 target 模板
?
你可能會注意到,除了默認的Info.plist之外,這個 extension 還包含另外兩個文件:
?
-
MainInterface.storyboard : 我們把自定義通知界面的 UI 畫在這里
-
NotificationViewController.swift : 一個 UIViewController 的子類,這就是自定義界面的 ViewController,我們通過這個類來管理自定義的界面。
?
把 Extension 與通知 category 關聯起來
?
現在工程設置好了,我們需要讓系統知道,是哪個通知要展示這個界面。不知道你記不記得,上一篇文章講過,一個 category 就是一個很簡單的對象(參考 UNNotificationCategory),里面定義了你的 app 支持哪些類型的通知,以及每種通知關聯了什么操作——就是用戶把通知展開的時候,通知下面出現的那些操作按鈕。
?
具體實現這一步,需要打開 extension 的 Info.plist,展開 NSExtensionAttributes Dictionary,把下面 UNNotificationExtensionCategory 這個鍵對應的值改為通知 category 的名字(“reminder”)。注意,這個值既可以填一個 string ,也可以填一個 string 數組,如果想讓多個通知 category 共用一個 extension 界面就可以填 string 數組。
?
Info.plist
?
現在把工程 Build、Run 一下,我們可以看到一個比默認的通知彈框更有意思一點的界面。
?
extension 的默認界面
?
管用了!現在用的是 extension 默認的 MainInterface.storyboard 界面,然后是 NotificationViewController 里的模板代碼在更新界面上的 label。不過這個界面還是有幾點需要改進的地方。首先,通知的內容(”Walk Dog!!”)在 extension 的界面上和 DefaultContent 區域重復出現了兩次。我們先把這個重復的去掉吧!
?
去掉 DefaultContent
?
很簡單,只需在 Info.plist 文件里的 NSExtensionAttributes 下面增加一個 key ,UNNotificationExtensionDefaultContentHidden,然后值設為 YES,就不會顯示 DefaultContent 了。
去掉 default content 之后
?
好,下面我們來寫自定義的界面吧。
?
自定義的通知界面
?
切換到 MainInterface.storyboard,加上 UI 控件。加一個 label 描述提醒的事項,加一個小喇叭的圖片。加完之后,只需拖幾個 IBOutlets 出來,就大功告成啦!
?
收到通知的時候,我們要更新 label 上的文本,同時搖晃小喇叭的圖片——用這種粗暴的方式吸引用戶的注意力。要實現這些功能,需要在 NotificationViewController 里進行一些修改。我們的 viewController 實現了 UNNotificationContentExtension 這個 protocol,下面用到的就是這個 protocol 中定義的方法:
?
func didReceive(_ notification: UNNotification) {
??label.text = "Reminder: \(notification.request.content.body)"
??speakerLabel.shake() // 具體實現下載源碼可以看到
}
?
這個方法就是收到通知之后,根據通知內容來配置通知界面的指定方法。
?
初步的通知界面
?
看起來還不錯,但是中間有一大段空白,看上去不大美觀。
?
幸運的是,要解決這個問題只需加 Info.plist 里再加一個 key UNNotificationExtensionInitialContentSizeRatio,它定義了自定義通知界面的高寬比。這個值可能需要多試幾次來調整,對于我們目前的情況取 0.5 就比較合適了(當寬度是 300 的時候,高度是 150)。
?
調整高寬比之后的界面
?
NotificationViewController?就是一個單純的 UIViewController 的子類,用起來跟你平常在主 app 里用普通的 viewController 是一樣的。唯一的不同點在于它的 userInteraction 是 disabled 的,意思是完全無法接收到用戶的點擊、觸摸事件。所以有部分控件是用不了的,比如 UIScrollView、UIButton 等。
?
接受用戶操作
?
自定義的界面我們畫出來了,但是還有一點要改進:點擊 “Cancel” 按鈕,只會讓用戶切回到鬧鐘 app,這一步有點多余。
?
在上一篇文章我們講了怎么給通知加上操作按鈕:通知出現時可以進行的每一項操作都是一個 UNNotificationAction,關聯在通知 category 上。更詳細的介紹可以參考官方文檔。
?
而 UNNotificationContentExtension 這個 protocol 提供了另一個處理點擊事件的方法:didReceive(_:completionHandler:)。我們就用這個方法,把小喇叭的 icon 改成紅線劃掉的小喇叭,然后把通知從 UNNotificationCenter 中移除。
?
func didReceive(_ response: UNNotificationResponse,
????????????????completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) {
?
??if response.actionIdentifier == "cancel" {
????let request = response.notification.request
?
????let identifiers = [request.identifier]
?
????// 移除后續的通知
????UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: identifiers)
?
????// 移除之前的通知,不在用戶的通知列表里占地方了
????UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: identifiers)
?
????// 通知取消的視覺反饋
????speakerLabel.text = "?"
????speakerLabel.cancelShake()
?
????completion(.doNotDismiss)
??}
??else {
????completion(.dismiss)
??}
}
?
相關的通知都移除了,UI 也更新了,接下來我們需要告訴系統該怎么處置這個通知界面。因為我們想讓用戶看到被劃掉的小喇叭,得到通知被取消的視覺反饋,所以要把通知留在屏幕上,因此回調里傳入 UNNotificationContentExtensionResponseOption 的一個取值 .doNotDismiss。
?
取消通知
?
既然要用這個方法處理點擊,就得處理好每一個按鈕事件。在這個例子里,我們只有一個“Cancel”按鈕。然而,如果還有別的按鈕,它們的點擊事件也需要處理好:要么也在 extension 工程的這個方法里處理,要么回調傳?UNNotificationContentExtensionResponseOption.dismissAndForwardAction,傳給主 app 去處理。
?
擴展閱讀
?
UserNotificationsUI 這個框架并沒有什么驚天動地的突破,但它能讓用戶與 app 的交互更便捷。用戶可以直接對通知進行操作,不用再切換到發出通知的 app 了;甚至通知界面的 UI 也能動態改變,來更好地反饋用戶操作的結果。
?
關于通知的其他“高級”特性,我推薦看看 WWDC 2016 的演講視頻。這場視頻中,演講者給出了幾個蘋果官方 app 自定義通知界面的例子,比如接收日程邀請。
?
轉載于:https://www.cnblogs.com/fengmin/p/6006688.html
總結
以上是生活随笔為你收集整理的iOS 10 的一个重要更新-自定义的通知界面的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到两条大蛇是什么意思
- 下一篇: 梦到捡了几块肉好不好