ワコムiOSインテグレーションガイド
iPadをお使いの方々の多くが、筆圧の微妙な変化を利用して本物のペンと紙のような描き心地を実現するソリューションを求めています。筆圧感知機能を備えた高性能スタイラスペン「Intuos Creative Stylus シリーズ」および「Bamboo Stylus fineline」を対応アプリケーションとともに利用することで、豊かな描画表現を可能にし、滑らかな描き心地を実現します。また、画面上に手を置いても誤動作を起こさず、絵筆や鉛筆で描くのと同じような自然で直感的な描画を楽しむことができます。
互換性
この機能は、ワコムのBluetooth LE接続のスタイラスペンにのみ対応しており、APIに筆圧とサイドスイッチの情報を提供するために、Bluetooth 4.0 Low Energyが必要です。
このため、この機能をサポートするデバイスは、2012年にRetina Displayを導入したiPadとそれ以降のタブレットに限定されます。
現時点では、iOS 6.1以降のみに対応しています。
機能
基本機能
このAPIを利用するには、Core Bluetooth Frameworkをリンクする必要があります。
加えて、デバイスを検知して接続する機能、またデバイスの筆圧とサイドスイッチの状態に関する情報を受け取る機能があります。
さらには、パームリジェクションを有効にする機能も用意しています。
種類
WacomManager
シングルトンとして機能し、さまざまなスタイラスへの接続を管理することを目的とするメインマネージャーです。
WacomDevice
スタイラスの名前やユニークIDなどの情報を持つクラスです。
WacomStylusEvent
筆圧やサイドスイッチが変更された時に、送出されるクラスです。
TouchManager
すべてのタッチデータ用メインマネージャです。TrackedTouchesを全般的に保存し、管理します。
TrackedTouches
パームリジェクションの基本単位です。パームリジェクションを提供するためには、ペンとそれ以外を識別できるように、タッチ回数とそれがいつ発生したかを知る必要があります。
機能の基本構成
マネージャを取得し、startDeviceDiscoveryを呼び出して検出処理を開始します。
その後、コールバックを受信するか、またはデバイス検出を停止するかを選択できます。
デバイス検出が完了するか、デバイスが選択可能な状態になると、選択したデバイスを呼び出し、デバイスに渡します。
デバイスが適切に登録されると、スタイラスイベントが受信されるようになります。
想定される機能構成
WacomStylusEventCallBackプロトコルとWacomDeviceDiscoveryCallbackプロトコルを実装します。これにより、検出中にコールバックが可能になります。
@interface MyUIView : UIView <WacomDiscoveryCallback,WacomStylusEventCallback> - (void) stylusEvent:(WacomStylusEvent *)stylusEvent; - (void) deviceDiscovered:(WacomDevice *)device; - (void) discoveryStatePoweredOff; @end
[[WacomManager getManager] registerForNotifications]を呼び出して、クラスをイベントに登録します。
[[WacomManager getManager] registerForNotifications:self];
- [[WacomManager getManager] startDeviceDiscovery]を呼び出して、デバイス検出を開始します。
[[WacomManager getManager] startDeviceDiscovery];]
検出されたデバイスコールを受信し、そのコールを使って、提示するUIを更新します。
- (void) deviceDiscovered:(WacomDevice *)device { NSLog(@"Discovered a device"); //This is test code you could use to select the first device discovered. //[[WacomManager getManager] selectDevice:(WacomDevice *) device]; }
- [[WacomManager getManager] stopDeviceDiscovery]を呼び出し、デバイス検出を終了します。
[[WacomManager getManager] stopDeviceDiscovery];
- [[WacomManager getManager] selectDevice]を呼び出し、使用するデバイスを選択します。
[[WacomManager getManager] selectDevice:(WacomDevice *) device];
次のように、UI ViewのtouchesBeganで、イベントのタッチセットをマネージャーに渡します。
(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [[TouchManager GetTouchManager] addTouches:touches knownTouches:[event touchesForView:self] view:self]; }
次のように、UI ViewのtouchesMovedで、イベントのタッチセットをマネージャーに渡します。
[[TouchManager GetTouchManager] moveTouches:touches knownTouches:[event touchesForView:self] view:self];
以下を呼び出します。
NSArray *theTrackedTouches = [[TouchManager GetTouchManager] getTouches];
これにより、この時点で使用可能なUI Touchesのリストが返されます。
パームリジェクションを有効にしている場合、スタイラスペンのタッチのみが返されます。
パームリジェクションが無効の場合、現在のタッチがすべて返されます。
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { CGRect bounds = [self bounds]; @try { [[TouchManager GetTouchManager] moveTouches:touches knownTouches:[event touchesForView:self] view:self]; NSArray *theTrackedTouches = [[TouchManager GetTouchManager] getTouches]; for (UITouch * theTouch in theTrackedTouches) { //Do work here such as: current = touch.currentLocation; current.y = self.bounds.size.height - touch.currentLocation.y; previous = touch.previousLocation; previous.y = self.bounds.size.height - touch.previousLocation.y; // update to latest pressure value if (mPressure != mCurrentPressure) { mCurrentPressure = mPressure; } [self renderLineFromPoint:previous toPoint:current]; mPreviousPressure = mCurrentPressure; mCurrentPressure = mPressure; } } @catch (NSException *exception) { NSLog(@"uh oh"); } }
次のように、UI ViewのtouchesEndedで、イベントのタッチセットをマネージャーに渡します。
[[TouchManager GetTouchManager] moveTouches:touches knownTouches:[event touchesForView:self] view:self]; NSArray *theTrackedTouches = [[TouchManager GetTouchManager] getTouches]; // Do work here… [[TouchManager GetTouchManager] removeTouches:touches knownTouches:[event touchesForView:self] view:self];
これにより、この時点で使用可能なUI Touchesのリストが返されます。
パームリジェクションを有効にしている場合、スタイラスペンのタッチのみが返されます。
パームリジェクションが無効の場合、現在のタッチがすべて返されます。
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint current, previous; [[TouchManager GetTouchManager] moveTouches:touches knownTouches:[event touchesForView:self] view:self]; NSArray *theTrackedTouches = [[TouchManager GetTouchManager] getTouches]; for(UITouch *touch in theTrackedTouches) { //Do work here. } [[TouchManager GetTouchManager] removeTouches:touches knownTouches:[event touchesForView:self] view:self]; }
TrackedTouchの現在の位置と以前の位置を使用し、簡単に線を描けます。
これらの座標はスタイラスペンの精度を高めるために修正されています。
現在のタッチの位置と以前のタッチの位置には修正されていないタッチの位置が含まれています。
次のように、UI ViewのtouchesCancelledで、イベントのタッチセットをマネージャーに渡して、タッチがクリアされたことを確認します。
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [[TouchManager GetTouchManager] removeTouches:touches knownTouches:[event touchesForView:self] view:self]; }
最後に、スタイラスイベントを受信する機能が必要になります。
以下にサンプルを示します。
使用する筆圧を加える方法については、Wacom Stylus Demo Appを参照してください。
GL Paint Appで使用されている各種の設定も確認できます。
ペンの固有ID(MACアドレス)が必要な場合は、デバイスが一旦ペアリングされると即座には取得できないので、スタイラスイベントの使用をおすすめします。
-(void)stylusEvent:(WacomStylusEvent *)stylusEvent { switch ([stylusEvent getType]) { // case eStylusEventType_MACAddressAvaiable: // NSLog(@"Mac address was %@", [stylusEvent getMACAddress]); // break; case eStylusEventType_PressureChange: //Pressure data received. break; case eStylusEventType_ButtonReleased: switch ([stylusEvent getButton]) { case 2: { //button 2 clicked } break; case 1: { //button 1 clicked } break; default: break; } break; default: break; } }
スタイラスから切断する場合は、選択解除機能を呼び出します。[[WacomManager getManager] deselectDevice]を呼び出し、選択したデバイスから切断します。
[[WacomManager getManager] deselectDevice:(WacomDevice *) device];
別の検討事項として、バックグラウンド/フォアグラウンド遷移の追加があります。
遷移はSDKにより自動的に処理されます。
これにより、スタイラスペンは切断され、他のアプリケーションで使用可能になります。
スタイラスペンは、アプリケーションを再度開くと自動的に再接続されます。
また、Interface Builderまたは次のコマンドを介してViewでマルチタッチ入力を有効にすることができます。
[self setMultipleTouchEnabled:YES];
最適な利き手操作を行うには、TouchManagerで利き手の設定をする必要があります。
これにより、スタイラスペンの精度を高めるためのヒントがライブラリに提供されます。
[[TouchManager GetTouchManager] setHandedness:eh_Left]; // or eh_Right
画面に手をつけて描く場合のマルチタスクジェスチャー
このSDKの使用中、画面に手をつけて描こうとする際にジェスチャーとマルチタスクジェスチャーの問題が生じます。
画面に手をつけて描く際には、ジェスチャーを無効にすることをおすすめします。
無効にするには、いくつかの方法があります。
スタイラスペンのサイドスイッチの機能を切り替える設定とし、デバイスが切断されたら再有効化する方法やツールバーにボタンを作成する方法があります。
しかし、一般的な設定では、画面に手をつけて描くことによりマルチタスクジェスチャーが発動されやすいため、マルチタスクジェスチャーが問題となります。
ワコムのスタイラスペンとのインテグレーションに関する質問や不明点は、vm-info(at)wacom.co.jpへご連絡ください。
信号制御の範囲
iPadに最も近いデバイスだけへの接続を容易にするため、スタイラスペンではデバイス検知時にRSSIを使用します。
設定は、0から-100までの間で調整でき、ペアリングにおける現在の規定値は-60となっています。次のコマンドで調整可能です。
[[WacomManager getManager] setMinimumSignalStrength:(int)value]
初回接続時で自動ペアリングが行われる際には、この設定によって、正常なペアリングが確立される可能性が高いと現時点では考えられています。
範囲の予測としては、約28インチ以上はペアリングに選択されませんが、信号強度というのは難しいもので、時によっては、遠く離れたデバイスを検知する場合もあります。
ただ、概ねこの調整を行ったほうが良い結果になると考えられています。
必要に応じて、設定値を-100にするとすべてのデバイスが常に表示されます。
パームリジェクションとタイミング
パームリジェクションコードがストロークを低下させたり、手をスタイラスと誤認したりする場合は、SDKのパームリジェクションコードのタイミングを調整する必要があるかもしれません。
調整は、[[TouchManager GetTouchManager] setTimingOffset:(unsigned int)]で数値の変更を行います。
規定値は、55000マイクロ秒となっており、パームリジェクションが手を認識する場合は時間を減らしたり、ストロークが低下している場合は、時間を増やしたりして調整します。
質問は、vm-info(at)wacom.co.jpへご連絡ください。
テスト時における注意
ワコムのスタイラスペンを支えるパームリジェクションや他のテクノロジーには、方向依存性がありますので、方向によっては若干異なった動作が生じます。
SDKを追加する際には必ずアプリが対応するすべての方向で機能するよう確認してください。