41
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Swiftで3D Touch

Last updated at Posted at 2016-08-18

#3D Touchについて
##実装に必要なもの
####シミュレータで見る場合
・Xcode7.3以上
・iPhone 6s/6s Plus以降
・iOS9以上
・Force touchが使えるトラックパッドが必要
####実機で見る場合
・Xcode7.1以上
・iPhone 6s/6s Plus以降
・iOS9以上

デフォルトでは3D Touchできるようになっているが、無効にしている場合は
設定>一般>アクセシビリティ> 3Dタッチ
で設定し直してください。
因みにここで感度を変える事ができ、3D Touchのテストもできます。

##用語一覧 Appleの3D Touch

Peek And Pop(軽くプレス時に表示される) Peek Quick Actions(Peek時に上にスワイプして出てくる) Home Screen Quick Action(アイコンをプレスすることで現れるアクション)

####UIViewControllerPreviewingDelegateプロトコル
Peekとして表示される

.swift
func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {}

とPopする直前に呼ばれる処理

.swift
func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {}`    

が必須です。

ビューをPeek and Popの対象にする

.swift
if self.traitCollection.forceTouchCapability == UIForceTouchCapability.Available {
  registerForPreviewingWithDelegate(self, sourceView: view)
}

####実装方法

.swift
extension ViewController: UIViewControllerPreviewingDelegate {
  func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
      let secondVC = storyboard?.instantiateViewControllerWithIdentifier("secondVC") as! SecondViewController
      // Peek(軽くプレス)で呼ばれるViewController
      return secondVC
  }
  func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {
      // viewControllerToCommitはPeek時にセットされたViewController
      // 今回はNavigationViewControllerを継いでるのでshowViewControllerを使うがそうじゃない場合はpresentViewControllerでモーダル表示
      showViewController(viewControllerToCommit, sender: self)
      
      // Peekとは違う画面をPopで表示する事もできる
      // let thirdVC = storyboard?.instantiateViewControllerWithIdentifier("thirdVC") as! ThirdViewController
      // showViewController(thirdVC, sender: self)
  }

上記のコードの説明

  1. previewingContext
    プレビューのコンテキストオブジェクトで
    previewingContextにはsourceViewがあります。
.swift
if previewingContext.sourceView is UIButton {
    // do something
  } else if previewingContext.sourceView is UILabel {
    // do something
  }

こんなことができる。

2.location
tableView.indexPathForRowAtPoint(location)
TableViewを使っている時のどのセルをプレスされているかが取得できる

3.ViewControllerではなく、nilを返す事で無効にできる
###Home Screen Quick Action
####実装方法
やり方は2通りあり、
・info.plistに追加する方法
・コードで追加する方法
があります。

#####info.plistで実装

.xml
<key>UIApplicationShortcutItems</key>
    <array>
        <dict>
            <key>UIApplicationShortcutItemIconType</key>
            <string>UIApplicationShortcutIconTypePlay</string>
            <key>UIApplicationShortcutItemTitle</key>
            <string>SEARCH</string>
            <key>UIApplicationShortcutItemType</key>
            <string>$(PRODUCT_BUNDLE_IDENTIFIER).Search</string>
        </dict>
        <dict>
            <key>UIApplicationShortcutItemIconType</key>
            <string>UIApplicationShortcutIconTypeAdd</string>
            <key>UIApplicationShortcutItemTitle</key>
            <string>ADD</string>
            <key>UIApplicationShortcutItemType</key>
            <string>$(PRODUCT_BUNDLE_IDENTIFIER).Add</string>
        </dict>
    </array>

これでホームアイコンをプレスするとADDとPLAYが表示される。

#####コードで実装する方法

.swift
let shortcut = UIMutableApplicationShortcutItem(type: "UIApplicationShortcutIconTypePlay", localizedTitle: "SEARCH", localizedSubtitle: "再生する", icon: UIApplicationShortcutIcon(type: .Play), userInfo: nil)
            UIApplication.sharedApplication().shortcutItems = [shortcut]

コードとplistでの実装の違い
コードで実装する場合、アプリをインストールしてから一度アプリを起動する必要がある。
info.plistで実装する場合、アプリをインストール直後から実装されるが、動的に変えることができない。

下の画像は3D Touch の Home Screen Quick Actions に対応するから引用

iOS9.0で使えるアイコン達
つまり上記のコードではADDとPLAYが表示されます。

この中にアイコンがない場合は(自作でやりたい場合)

.xml
<dict>
    <key>UIApplicationShortcutItemIconFile</key>
    <string>(画像)</string>
    <key>UIApplicationShortcutItemTitle</key>
    <string>SEARCH</string>
    <key>UIApplicationShortcutItemType</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER).Search</string>
</dict>

UIApplicationShortcutItemIconFileを設定するとUIApplicationShortcutItemIconTypeは強制的に適用されなくなるので意味なくなります。

アイコンをタップ時に通知されるメソッドはAppDelegateにあり、

func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void)

で取得する事ができ、実装方法としては

.swift
extension AppDelegate {
    
    private enum ShortcutItemType: String {
        case Play
        
        init?(shortcutItem: UIApplicationShortcutItem) {
            guard let last = shortcutItem.type.componentsSeparatedByString(".").last else { return nil }
            self.init(rawValue: last)
        }
        
        var type: String {
            return NSBundle.mainBundle().bundleIdentifier ?? "" + ".\(rawValue)"
        }
    }
    
    func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
        guard let itemType = ShortcutItemType(shortcutItem: shortcutItem) else { return }
        switch itemType {
        case .Play:
            // do something
            break
        }
    }
    
}

こんな感じで取得する事ができます。

iOS Human Interface Guidelines

  • PeekのViewでボタンの要素などをおくのはやめる。
    ユーザーがタップしようとして指を離したときに、Peekが消えるので

  • Peekだけというのは避ける
    Peek And Popは一貫して採用、Peekしかできない場合ユーザーのデバイスに問題があるのではないかと思われる為

  • Popを表示するためのアクションボタンをPeek quick actionsのボタンとして出すのはやめる。
    表示するために深くプレスするので。

  • Peek quick actionsのアクションでしかできないことにしないこと
    必ずしも全てのデバイスが3D Touchをサポートしてるとは限らないので

  • 適切なアクションボタンを用意しよう

  • Peekingと全く同じ編集ボタンを用意するのはやめよう

41
33
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?