2014年11月26日

UIKit Dynamics ステップアップチュートリアル in Swift (3)

前回「UIKit Dynamics ステップアップチュートリアル in Swift (2) 番外編 - TabBar」でタブバーに「Push」という名前で新規ビューコントローラーの雛形を追加しました。

今回は、その「Push」の機能を実装します。
要件は以下の通りです。

  • ダイナミクスの動作対象オブジェクトは赤の矩形(Rectangle) 。

  • 重力はなし

  • 上下方向にスワイプで、加速度が加算される




ということで、要約すると、上下のスワイプの方向に加速度を「プッシュ」する機能の実装です。
プロジェクトは前回のチュートリアルが終わった時点のものを想定しています。

PushViewController クラスの作成と割り当て


Step 1> PushViewController クラスの作成
[Project navigator](左パネル)> [MyDynamics] で[ctrol + click] でコンテキスト・メニューを表示。
コンテキスト・メニューから [New File...]を選択します。表示されたウィザードから[iOS] &gr; [Source] をクリック。「Cocoa Touch Class」を選択して [Next] ボタンをクリック。[Class] を「`PushViewController」 として [Next] ボタンをクリック。Swiftのクラスファイルを保存する場所を指定して [Create] ボタンをクリックで、「PushViewController」クラスの雛形が作成されます。

Step 2> Storyboard のビューコントローラーに割り当て
[Main.storyboad] をクリックして、前回「」で作成した、ビューコントローラを選択します。[Identity Inspector](右パネル)をクリック「Custom Class」のドロップダウンから「PushViewController」を選択します(図1)

assign_custom_push_viewcontroller.gif
図1 ビューコントローラ・クラスの割り当て

スワイプ・アクションのハンドリング


PushViewController に上下にスワイプするアクションのハンドリング処理を実装します。
セレクターには同じメソッド(respondToSwipeAction)を指定します。

Step 1> UISwipeGestureRecognizerの登録
viewDidLoad メソッドを以下のように変更して、上下スワイプアクション用のUISwipeGestureRecognizerを追加します。
override func viewDidLoad() {
super.viewDidLoad()

var swipeDown = UISwipeGestureRecognizer(target: self, action: "respondToSwipeAction:")
swipeDown.direction = UISwipeGestureRecognizerDirection.Down

self.view.addGestureRecognizer(swipeDown)

var swipeUp = UISwipeGestureRecognizer(target: self, action: "respondToSwipeAction:")
swipeUp.direction = UISwipeGestureRecognizerDirection.Up

self.view.addGestureRecognizer(swipeUp)
}


Step 2> セレクター・メソッドの実装

セレクター・メソッド、respondToSwipeAction、を次のように実装します。

func respondToSwipeAction(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case UISwipeGestureRecognizerDirection.Up:
println("Swiped Up...")
case UISwipeGestureRecognizerDirection.Down:
println("Swiped Down...")
default:
break
}
}
}


Step 3> 実行して確認
シミュレーターで実行して確認します。スワイプするとコンソールに処理されたログが出力されます。(図2)

swipe_handling.gif
図2 実行・確認(スワイプ)

矩形ボックス(UIViewオブジェクト)と UIDynamicAnimator の作成


PushViewController に矩形のオブジェクトと UIDynamicAnimator を作成します。

Step 1> クラスプロパティの定義
PushViewController クラスに矩形用の UIView オブジェクトと UIDynamicAnimator オブジェクトを定義します。
クラス宣言の下、viewDidLoadメソッドの上に、次のコードを記述します。
...
var boxView: UIView!
var animator: UIDynamicAnimator!


Step 2> 矩形オブジェクトの作成と配置
PushViewController クラスの "viewDidLoad" メソッドに以下のコードを追加します。
override func viewDidLoad() {
...
// ボックスオブジェクトの初期化
let w = 200
let h = 100
let x = Int(view.frame.width/2)-Int(w/2)
let y = Int(view.frame.height/2)-Int(h/2)
boxView = UIView(frame: CGRect(x: x, y: y, width: w, height: h))
boxView.backgroundColor = UIColor.redColor()
view.addSubview(boxView)
}


Optional Value の影響で、またまた冗長感がありますが、これで赤い長方形のオブジェクトが作成されます。

Step 3> 実行・確認
実行して確認してみてください。Dynamics の記述はまだしていません。したがって、オブジェクトは止まったままです。(図3)
sim_red_rect_object.png
図3 シミュレーターで実行(Pushタブ)

加速度の追加


オブジェクトに加速度を追加する関数を作成します。重力のように加速度が加え続けられるわけではないので、瞬間的に加えられたら、速度は一定で動作します。
加速度は上または下方向にスワイプする度に加えられます。したがいまして、スワイプを重ねるごとに速度は速くなります。また、方向の加速度は打ち消されて遅くなります。

Step 1> pushメソッドの作成
瞬間的に加速度を加えるための 「push」メソッドを定義します。以下のコードをPushViewControllerクラスのメソッドとして記述してください。
func push(angle: CGFloat) {
let instantaneousPush: UIPushBehavior = UIPushBehavior(items: [boxView], mode: UIPushBehaviorMode.Instantaneous)
instantaneousPush.setAngle( angle, magnitude: 0.3);
animator.addBehavior(instantaneousPush)
}

引数「angle」は加速度を加える方向です。ラジアンで指定します。加速度を加える動きは 「UIPushBehavior 」オブジェクトを使用します。「mode」の「 UIPushBehaviorMode.Instantaneous」 は瞬発的に加速度を指定する場合のモードです。重力のように一定の加速度がかかり続ける場合は「UIPushBehaviorMode.Continuous」を使います。

Step 2> スワイプのハンドラー・メソッドで呼び出し
スワイプのハンドラー・メソッド, "respondToSwipeAction", を以下のように書き換えます。

func respondToSwipeAction(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case UISwipeGestureRecognizerDirection.Up:
println("Swiped Up...")
self.push(-1.0*CGFloat(M_PI_2))
case UISwipeGestureRecognizerDirection.Down:
println("Swiped Down...")
self.push(CGFloat(M_PI_2))
default:
break
}
}
}

スワイプ・アップとスワイプ・ダウン、それぞれの方向で加速度を加えています。

Step 3> 実行と確認
シミュレーターで実行して確認してみます。
スワイプの度に加速度は加わり矩形の速度は増します。逆にスワイプすると、速度は弱まり停止の後は逆方向に動きます。(図4)
swipe_and_push.gif
図4 シミュレーターで実行(スワイプで加速)


今回は、ここまでです。
次回は、矩形が上下いずれかの境界(端)に達したらバウンスして止まる処理を加えます。

posted by ayagu at 17:16| Comment(2) | iOS | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
iOS7 - スクロールとちょっとだけ Auto Layout (2)

の続きをお願いします。。。
Posted by key at 2014年11月28日 19:39
ほんとうにお願いします。。。

参考にさせていただいているので、是非続きを書いてほしいです。


勝手で唐突ではありますが、お願いします。。。




Posted by key at 2014年11月30日 16:27
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。