読者です 読者をやめる 読者になる 読者になる

Swiftで遊ぼう! on Hatena

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

Swiftで遊ぼう! - 659 - UIGestureRecognizerState.Beganの処理がやっと終了

次のTable Viewのチュートリアルを拡張しています。

yataiblue.hatenablog.com

独自メソッド「snapshotOfCell()」のコードがやっと理解できました。UITableViewCell型のcellをロングプレスで選択した時にUIView型のスナップショットとして背景を付けて返すメソッドです。この独自メソッドをlongPressed()メソッド内で使用します。このデータをタイプ・プロパティとして用意した次の構造体に保持させます。

struct MyCell {
  static var cellSnapshot: UIView? = nil
  static var initialIndexPath : NSIndexPath? = nil
}

実は以下の内容に戻ってきただけです(^^;)
yataiblue.hatenablog.com
この中の「snapshotOfCell()」メソッドから見ていきます。

MyCell.cellSnapshot = snapshotOfCell(cell)
var center = cell.center
MyCell.cellSnapshot?.center = center
MyCell.cellSnapshot!.alpha = 0.0
simpleTableView.addSubview(MyCell.cellSnapshot!)

cellのcenter(センター)*1をsnapshotOfCellのcenterにします。

次にcellSnapshotの「alpha」を「0.0」に設定しています。要するに見えないように透明に設定して。そのままsimpleTableViewに加えるステップです。

そして今日の課題は次のクラス・ファンクションです。便利ですが取っつきにくいクロージャが使用されています。

UIView.animateWithDuration(0.25, animations: {
   center.y = locationInView.y
   MyCell.cellSnapshot!.center = center
   MyCell.cellSnapshot!.transform = 
         CGAffineTransformMakeScale(1.05, 1.05)
   MyCell.cellSnapshot!.alpha = 0.98
   cell.alpha = 0.0
  }, completion: { (finished) -> Void in
      if finished {
        cell.hidden = true
    }
})

1つのViewから他のViewにアニメーション効果を使って変遷させるクラス・ファンクションです。このコードはプログラミング初心者の人でも利用している人は多いので今更って思われるかもしれませんが、私は初めて遭遇しました。今までのチュートリアルにアニメーション効果が出て来なかったからです。今日しっかりと理解します。

class func animateWithDuration(_ duration: NSTimeInterval, animations animations: () -> Void, completion completion: ((Bool) -> Void)?)

duration: アニメーションの効果が持続する時間(秒)です。負の値や「0」を与えるとアニメーション効果は無くなります。
animations: ここにアニメーションの具体的なコードブロックを記述していきます。パラメータも受け取らないし戻り値も無いのでNULLになったらクラッシュします。

正式ににコードを書くと次のようになります。

animations: { () -> Voind in
 // メインのコードブロック
}

しかし、パラメータも戻り値も無いので「() -> Voind in」を全て省略して書けるので、上のコードブロックでは省いています。ではコードの中身を見ていきます。

locationInViewはロングプレスジェスチャーが発動した位置*2を保持しているので、その垂直情報(y)を変数centerに渡してからMyCellで保持しているcellSnapshotに与えています。

func CGAffineTransformMakeScale(_ sx: CGFloat, _ sy: CGFloat) -> CGAffineTransform

この関数の戻り値のCGAffineTransformという構造体が気になりますね。非常に数学的でじっくり考えたいのですが、今日はさらっと流します。
使い方は他の人の書いている情報で勉強します。

blog.3streamer.net

ということで、「CGAffineTransformMakeScale(1.05, 1.05)」は元のviewを1.05倍に拡大したということです。

そして透明だったcellSnapshotのalpha値を「0.98」まで不透明にすることで出現させて、元々見えていたcellを透明にします。

completion: animateWithDurationメソッドの最後のパラメータはcompletionハンドラーですね。完了時に成功していたら元々存在するcellをテーブルから隠すという操作になります。

completion: { (finished) -> Void in
   if finished {
     cell.hidden = true
   }
}

これでロングプレスジェスチャーが発動した時に呼ばれた時の動作がすべて完了です。少し指を動かすと「state」は「.Began」から「.Changed」に変化するので、case文を使って対応します。

今日はここまで。

*1:そのオブジェクトの中心では無く、オブジェクトの中心がViewのどの位置にあるかです-> Swiftで遊ぼう! - 249 - UIViewの座標システム - Swiftで遊ぼう! on Hatena

*2:ここで定義しています->Swiftで遊ぼう! - 652 - longPressed()はまだまだ準備中(^^;) - Swiftで遊ぼう! on Hatena