3D Touch應用:快捷功能

這邊說明App透過3D Touch所使用的快捷功能(雖然這個功能簡直雞肋,但總得嘗試一下)。

快捷功能分成靜態動態,靜態的設定很簡單,只要去Info.plist中加入一個UIApplicationShortcutItems陣列,並加入下列屬性:

必要屬性

  1. UIApplicationShortcutItemType:快捷功能的識別碼,在所有App中都是唯一的,所以通常都會在識別碼前加上Bundle ID,避免重複。
  2. UIApplicationShortcutItemTitle:這個功能的名稱。

非必要屬性

  1. UIApplicationShortcutItemSubtitle:副標題。
  2. UIApplicationShortcutItemIconType:指定來自系統函式庫的圖示類型,至於圖示類型則參考官方文件。
  3. UIApplicationShortcutItemIconFile:使用自己的圖示。
  4. UIApplicationShortcutItemUserInfo:一些想傳遞的資訊…?

基本上只要設定好就可以直接啟用了,完全不需要任何程式碼。

接著是動態的快捷,為了讓快捷功能有更多彈性,才會需要動態快捷。例如我們強迫使用者第一次進入過App之後才啟用快捷。

首先透過UIForceTouchCapability檢查裝置是否支援3D Touch,接著設定快捷鍵內容,下面範例我們設置兩個快捷鍵:

if traitCollection.forceTouchCapability == UIForceTouchCapability.available{
let bundleID = Bundle.main.bundleIdentifier
let shortcutItem1 = UIApplicationShortcutItem(type: “\(bundleID).NewRestaurant”, localizedTitle: “New Restaurant”, localizedSubtitle: nil, icon: UIApplicationShortcutIcon(type: .add), userInfo: nil)//icon使用內建的add,也就是+號
let shortcutItem2 = UIApplicationShortcutItem(type: "\(bundleID).OpenDiscober", localizedTitle: "Discover Restaurant", localizedSubtitle: nil, icon: UIApplicationShortcutIcon(templateImageName:"discover"), userInfo: nil)//icon使用我們指定的圖示
UIApplication.shared.shortcutItems = [shortcutItem1, shortcutItem2]
}

接著要實作讓程式啟動快捷功能。在iOS 9之後,有一個定義在UIApplicationDelegate協定的方法「application(_:[performActionFor:completionHandler:)」,當使用者選擇快捷功能會呼叫這個方法。在AppDelegate中實作這個方法:

首先宣告一個enum:

//先宣告一個列舉,在case中定義快捷功能,並將完整的識別碼轉換成對應列舉的case
enum QuickAction:String{
case NewRestaurant = “NewRestaurant”
case OpenDiscover = “OpenDiscover”
init?(fullIdentifier: String){
guard let shortcutIdentifier = fullIdentifier.components(separatedBy: “.”).last
else{
return nil
}
self.init(rawValue: shortcutIdentifier)
}
}

實作application(_:[performActionFor:completionHandler:),我們在裡面呼叫handleQuickAction方法:

func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
completionHandler(handleQuickAction(shortcutItem: shortcutItem))
}
private func handleQuickAction(shortcutItem: UIApplicationShortcutItem) -> Bool
{
let shortcutType = shortcutItem.type
guard let shortcutIdentifier = QuickAction(fullIdentifier: shortcutType)
else{
return false
}
guard let tabBarController = window?.rootViewController as? UITabBarController
else{
return false
}
switch shortcutIdentifier {
case .NewRestaurant:
if let navController = tabBarController.viewControllers?[0]{
//從tabbar取得第一個,也就是Restaurant Table View,接著呼叫addRestaurant這個segue,讓他導向頁面
let restaurantTableViewController = navController.childViewControllers[0]
restaurantTableViewController.performSegue(withIdentifier: “addRestaurant”, sender: restaurantTableViewController)
}else{
return false
}
case .OpenDiscover:
tabBarController.selectedIndex = 1 //Discover是tabbar的第二個選項
}
return true
}

case的部分根據App的功能做設定,因此寫法很多種,這是100Flavor App的一部分。

專案參考:AppDelegate.swift