Swiftで遊ぼう! on Hatena

あしたさぬきblogでやってた初心者オヤジのiOSプログラミング奮闘記がHatenaに来ました

Swiftで遊ぼう! - 421 - UIKit Dynamics and Swift Tutorial: Tossing Views 2

Swiftで遊ぼう!の古い記事-> Life-LOG OtherSide

Dynamicsのチュートリアルに取り組んでいます。

www.raywenderlich.com

前回メソッドを書いたところで終了しました。もう既に理解出来ているのですが、@IBActionという枕詞は必ずstoryyboardにジェネリックなオブジェクトを作る必要があります。

@IBAction func handleAtttachmentGesture(sender: UIPanGestureRecognizer) {
 let location = sender.locationInView(self.view)
 let boxLocation = sender.locationInView(self.imageView)
        
 switch sender.state {
  case .Began:
   print("\(location)からタッチが始まります。")
   print("\(boxLocation)はイメージを中心とした開始点です。")
  case .Ended:
   print("\(location)でタッチは終了です。")
   print("\(boxLocation)はイメージを中心とした終点です。")
  default:
   break
 }
}

オブジェクト・ライブラリから「Pan Gesture Recognizer」をMain.storyboardにドラッグ&ドロップすると、上部に「Pan Gesture Recognizer」が追加されるので、それを隣の「View Controller」に「Ctrl + ドラッグ」する。メニューウインドウが出現するので、「@IBAction」の枕詞が付いたメソッドのhanleAttachmentGestureを選ぶと繋がります。

次に℃フォルトのviewを物理空間にしなければならないので、viewDidLoad()メソッド内に次のコードを加えます。

animator = UIDynamicAnimator(referenceView: view)
originalBounds = imageView.bounds
originalCenter = imageView.center

次はジェスチャーと物理空間の融合です。これは先ほど実装したhandleAttachmentGesture()メソッドの中に物理空間のルールを組み入れていくといいんですね。

PanGestureの始まりを認識したところが「case .Bagan:」なのでここから実装を始めます。

まず最初のコードは分かります。

animator.removeAllBehaviors()

まずanimator空間をリセットします。

let centerOffset = UIOffset(horizontal: boxLocation.x - imageView.bounds.midX,
                            vertical: boxLocation.y - imageView.bounds.midY)
attachmentBehavior = UIAttachmentBehavior(item: imageView,
    offsetFromCenter: centerOffset, attachedToAnchor: location)

ここで私には聞き慣れない言葉が出てきました。「オフセット」です。これを調べて見ると、オブジェクトの位置を、ある基準点から引いた値で表したものをオフセット値というようです。ここで何をしているのかと言えば、imageViewの位置は、そのboundsの中点を基準にして引いた値をcenteOffset値にしています。

そして、attachmentBehaviorはこのオフセット値で作っています。

こういうやり方で基準をとるようです。

次にドラッグを追尾するredSquareにアンカーポイントを代入します。
そして、blueSquareに最初のスタート地点を代入して、動きを加えてます。

redSquare.center = attachmentBehavior.anchorPoint
blueSquare.center = location
animator.addBehavior(attachmentBehavior)

ここまでのコードブロックを「.Begin」のケースに入力します。

ドラッグし続けると「default:」が作動されるので、次のコードを「default:」以下に加えます。

default:
 attachmentBehavior.anchorPoint = sender.locationInView(view)
 redSquare.center = attachmentBehavior.anchorPoint

ここまで入力してラン(Cmd + R)してみる。

いやあ本当に楽しい。これだけでイメージがズリズリと動きます。簡単にアニメーションを組み込むことができるんですね。

UIKit Dynamiceのことについて少し整理します。

UIKit Dynamicsはゲームエンジンとして使うべきではないんです。故意にviewを単純な四角形のブロックとしてマンガチックに扱っています。そのため、中心点をアニメーションで動かし二次元空間でしか回転されることしかできません。CIFilterのアニメーションと似ていて*1、UIKit DynamicsはCADisplayLinkに依存しているので、メインスレッドでのみフレーム計算が実行されます(バックグラウンドではできません)。「アニメーションムービー」や個別の「プレゼンテーションレイヤー」を持っていないので、リアルタイムにviewを変化させられるだけです。したがってUIKit Dynamicsは、拡張利用を意図されて無く、単純にユーザーインターフェイストランジションを明確化させる方法の1つという訳です。

今日はここまで。

*1:CIFilterはまだ全然わかりません。