ZhgChg.Li

iOS APPに3D TOUCH機能を追加|Swiftでユーザー体験を向上させる方法

iOSアプリ開発者向けに、Swiftを使って3D TOUCH機能を実装しユーザー体験を改善。操作の迅速化と直感的な操作感を実現し、アプリの魅力を効果的に向上させる具体的手法を解説。

iOS APPに3D TOUCH機能を追加|Swiftでユーザー体験を向上させる方法
本記事は AI による翻訳です。お気づきの点があればお知らせください。

[廃止予定]ユーザー体験を向上させるために、今すぐあなたのiOSアプリに3D TOUCH機能を追加しましょう(Swift)

iOS 3D TOUCH の活用

[廃止] 2020/06/14

iPhone 11以降のモデルでは3D Touch機能が廃止され、Haptic Touchに置き換えられています。実装方法も異なります。

先日、プロジェクト開発の合間に多くのiOSの面白い機能を探りました: CoreMLVisionNotification Service Extension 、Notification Content Extension、Today Extension、Core Spotlight、Share Extension、SiriKit(一部は記事にまとめ済み、その他はお楽しみに🤣)

その中でも本日の主役は:3D Touch機能

この機能は iOS 9/iPhone 7以降 でサポートされており、私自身がiPhone 6からiPhone 8に変えて初めてその便利さを実感しました!

3D TouchはAPPで以下の2つの機能を実装できます:

1. Preview ViewController プレビュー機能 — 結婚吧APP

  1. Preview ViewController プレビュー機能 — 結婚吧APP

2. 3D Touch ショートカットアプリ起動機能

  1. 3D Touch ショートカットアプリ起動機能

その中で、第一の機能は最も広く使われ、効果も高いものです(Facebook:ニュースフィードの内容プレビュー、Line:メッセージのチラ見)。第二のAPPショートカット起動は、現在のデータを見ると利用者が少ないため、最後に説明します。

1. Preview ViewController プレビュー機能:

機能のデモは上の図1に示されているように、ViewControllerのプレビュー機能をサポートしています。

  • 3D Touchの強押し時の背景のぼかし

  • 3D Touchで強く押したときにViewControllerのプレビューウィンドウを表示する

  • 3D Touchで強く押すとViewControllerのプレビューウィンドウが表示され、上にスワイプすると下部にオプションメニューを追加できる

  • 3D Touchの強押しを離してウィンドウに戻る

  • 3D Touchで強く押してからさらに力を入れて目的のViewControllerに遷移する

ここでは、A:リスト画面B:ターゲット画面 に分けて実装するコードをそれぞれ示します:

B内では現在がプレビューか実際に画面に入っているかを判別する方法がないため、判定用の値を渡すProtocolを先に作成します。

protocol UIViewControllerPreviewable {
    var is3DTouchPreview:Bool {get set} // 3D Touchプレビューかどうか
}

これで B 内で以下の判定ができるようになります:

class BViewController:UIViewController, UIViewControllerPreviewable {
     var is3DTouchPreview:Bool = false
     override func viewDidLoad() {
     super.viewDidLoad()
     if is3DTouchPreview {
       // プレビュー画面の場合…例えば:全画面表示にする、ツールバーを隠す
     } else {
       // 通常モードでは通常通り表示
   } 
}

A: リストビューは UITableView または UICollectionView で構成できます:

class AViewController:UIViewController {
    //3D Touchが使えるViewを登録
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        if traitCollection.forceTouchCapability == .available {
            //TableView:
            registerForPreviewing(with: self, sourceView: self.TableView)
            //CollectionView:
            registerForPreviewing(with: self, sourceView: self.CollectionView)
        }
    }   
}
extension AViewController: UIViewControllerPreviewingDelegate {
    //3D Touchを離した後の処理
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
        
        //これから直接遷移するページなので、ViewControllerのプレビューモードを解除:
        if var viewControllerToCommit = viewControllerToCommit as? UIViewControllerPreviewable {
            viewControllerToCommit.is3DTouchPreview = false
        }
        self.navigationController?.pushViewController(viewControllerToCommit, animated: true)
    }
    
    //3D TouchのCell位置と表示したいViewControllerを制御
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
        
        //現在のタップ位置のindexPathとcellの取得
        //TableView:
        guard let indexPath = TableView.indexPathForRow(at: location),let cell = TableView.cellForRow(at: indexPath) else { return nil }
        //CollectionView:
        guard let indexPath = CollectionView.indexPathForItem(at: location),let cell = CollectionView.cellForItem(at: indexPath) else { return nil }
      
        //表示したいViewController
        let targetViewController = UIStoryboard(name: "StoryboardName", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerIdentifier")
        
        //背景をぼかす際の保持領域(通常はタップ位置)、図1参照
        previewingContext.sourceRect = cell.frame
        
        //3D Touchウィンドウのサイズ、デフォルトは自動調整で変更不要
        //変更する場合は:targetViewController.preferredContentSize = CGSize(width: 0.0, height: 0.0)
        
        //プレビューのViewControllerに現在プレビューモードであることを通知:
        if var targetViewController = targetViewController as? UIViewControllerPreviewable {
            targetViewController.is3DTouchPreview = true
        }
        
        //nilを返すと何の効果もなし
        return nil
    }
}

ご注意ください!3D Touchを登録するViewは“viewDidLoad”ではなく、traitCollectionDidChange内に配置する必要があります(こちらの記事を参照してください

どこに追加すべきかについて、多くの失敗を経験しました。ネット上ではviewDidLoadに書く場合もあれば、cellForItem内に書く場合もありますが、どちらも時々動作しなかったり、一部のセルだけが動作しない問題が発生します。

附図1 背景ぼかし保持領域のイメージ

付図1 背景ぼかし保持領域のイメージ図

もしスワイプアップ後に下部にオプションメニューを追加したい場合は、B の中に追加してください。BはB、BはBですよ!

override var previewActionItems: [UIPreviewActionItem] {
  let profileAction = UIPreviewAction(title: "店舗情報を見る", style: .default) { (action, viewController) -> Void in
    // タップ後の操作
  }
  return [profileAction]
}

空の配列を返すことでこの機能を使用しないことを示します。

完了!

2. APP ショートカット起動

ステップ1

info.plist に UIApplicationShortcutItems パラメータを追加し、タイプは Array に設定する

そして、その中にメニュー項目(Dictionary)を追加し、キーと値の設定は以下の通りです:

  • [必須] UIApplicationShortcutItemType : 識別文字列で、AppDelegateで判定に使用します

  • [必須] UIApplicationShortcutItemTitle : オプションのタイトル

  • UIApplicationShortcutItemSubtitle : オプションのサブタイトル

  • UIApplicationShortcutItemIconType : システムアイコンを使用する

参照元 こちらの記事

参考元はこちらの記事です。

  • UIApplicationShortcutItemIconFile : カスタムアイコンを使用(サイズ:35x35、単色)、UIApplicationShortcutItemIconTypeとどちらか一方を使用します

  • UIApplicationShortcutItemUserInfo : 追加情報の詳細例 EX: [id:1]

私の設定は上の画像の通りです

私の設定は上の図の通りです

第二ステップ

AppDelegateに処理用の関数を追加する

func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
    var info = shortcutItem.userInfo
  
    switch shortcutItem.type {
    case "searchShop":
      //
    case "topicList":
      //
    case "likeWorksPic":
      //
    case "marrybarList":
      //
    default:
        break
    }
    completionHandler(true)
}

完了!

結語

APPに3D Touch機能を追加するのは難しくなく、ユーザーにとっても親切に感じられます❤;デザイン操作と組み合わせてユーザー体験を向上させることができます;しかし現在は上記の2つの機能しかなく、さらにiPhone 6s以下やiPad、iPhone XRは3D Touch非対応のため、実際に使える機能はさらに限られています。あくまで補助的に体験を増やす目的となります。

p.s.

もし細かくテストすると、上記の効果がわかります。CollectionViewをスクロールしているときに一部の画像が画面外に出ている状態で強く押すと、上記のような現象が起こります😅

もし細かくテストすると、上記の効果で、CollectionViewをスクロールしているときに一部の画像が画面外に滑り出している状態で押し込むと、上記のような状況が発生することに気づくでしょう😅

Post が Medium から ZMediumToMarkdown によって変換されました。

GitHub で編集
この記事を改善
本記事は Medium で初公開
オリジナルを読む
この記事をシェア
リンクをコピー · SNS でシェア
ZhgChgLi
著者

ZhgChgLi

An iOS, web, and automation developer from Taiwan 🇹🇼 who also loves sharing, traveling, and writing.

コメント