大坪と申します。Simple Exampleシリーズと称して「ググれば見つかるけど、ちょっとわかりづらい」iOS上でのテクニックについて
・実行できるサンプルプロジェクト付(動かないとわかんない)
・肝心な部分を動かすのに必要最低限のコードを書く。余計なものは一切つけない(ごてごて余計なものがあるとどこが肝かわからない)
をモットーにサンプルコードを解説&公開していきます。第一弾は「UICollectionViewのframeをアニメーション付きで変更する」方法について。
UICollectionViewというのは私見では実に偉大な画面部品で、あちこちで使いたくなります。その際「何かのアクションでUICollectionViewのframeを変更する」ということがあると思います。
というわけで、githubにおいたのサンプルコードを実行してみてください。こんな画面が表示されるはずです。
左端にUICollectionViewが表示されています。画面右側一番上の"Frame Change"を押してみてください。いきなりUICollectionViewの外枠とセルが変化します。
プログラム的には
UICollectionView.frame = newFrame;
(ViewController.mのsimpleChange:(UIButton*) buttonの処理
としただけです。
これで用が足りる場合もあるでしょうが、iOSでプログラムを書いていると「アニメーションで変化させたい」と思うことでしょう。実際UIView animationWithDuration:は偉大で、ブロックの中に変化させる処理を書けば、たいていのことはアニメーションで変化させてくれます。ではさっそくframeの変更処理をUIView animationWithDuration:の中にいれてやりましょう。
画面のFrame Change + UIView animationを押すとこの処理が実行されます。
確かにアニメーションするのですが、なんとなく動きが期待と違うと思います。とくにUICollectionViewの幅が狭くなる時には、セルが縦一列にいきなり移動し、そのあとアニメーション付きでUICollectionViewのframeが変化する。これはあまり美しくない。
というわけで、一番下のCombo Changeを押してみてください。frameの変形だけではなく、セルの移動にもアニメーションがついたのがわかると思います。
これをどうやって実現しているかというと、ViewController.mのcomboChange:(UIButton*) buttonをみてください。
ほとんどの処理は先ほどのanimChangeと同じですが、その外側に_collectionViewController.collectionView performBatchupdates:がついています。これがつくとセルまでちゃんとアニメーションしてくれる、というわけでした。
みんな大好きStackoverflowにもいくつか回答があるのですが、そこにたどり着くまでかなり苦労したので、ご参考になれば。