みずぴー日記

月に行こうという目標があったから、アポロは月に行けた。飛行機を改良した結果、月に行けたわけではない。

💪3D Touchサポートの実験

FlickSKKで3D Touchをサポートするために、いくつかの実験的な実装を行なった。

既存のAPIの問題点

iPhone 6s/6s Plusで3D Touchが搭載されたが、APIから利用できるのは以下の3機能のみ*1である。(参考: iOS - 3D Touch 概要 - Qiita)

  • home screenにおけるQuick Action
  • peek/pop
  • 圧力感知(フィードバックなし)

そのため強く押されたときに、フィードバック付きで任意のアクションを実行することはできない。

実現したこと

f:id:mzp:20151115154813g:plain

  • 押す力が一定値以下の場合は何もおきない。
  • 一定値以上になると、押す力に応じて画面にぼかしをかける。
  • さらに強く押すと、hapticによるフィードバックが発生し、漢字変換を開始する。

要素技術

Taptic Engineによるフィードバック

TapticEngineを直接使うAPIは公開されていない。 しかし、公開されていないだけで実装はされているので、ヘッダファイルを自分で書けば利用できる。(参考: Using Taptic Engine on iOS · Unified Sense)

#ifndef Taptic_h
#define Taptic_h

#import <UIKit/UIKit.h>

@interface UITapticEngine : NSObject
- (void)actuateFeedback:(int)feedbackType;
@end

@interface UIDevice (Private)
- (UITapticEngine *)_tapticEngine;
@end

#endif /* Taptic_h */

使い方は以下の通り。

UIDevice.currentDevice()._tapticEngine().actuateFeedback(1001)

押下時のぼかしの適用

押してる圧力は分かりづらいので、画面上になんらかのフィードバックを出すようにしたほうがいい。 今回は、圧力に応じて、画面にぼかしをかけるようにした。

UIBlurEffectを利用しようとしたが、ぼかしの強さを変更できないので断念した。

そこで、画面のスクリーンショットを取得し、UIImage+ImageEffects.hを用いて、ぼかしをかけるようにした。

その他

より具体的なことはPull request #143を直接見れば分かる。 特にForceTouch.swiftに説明コメントが多めにはいっている。

*1:iOS 9.1時点