2015年10月25日日曜日

UIImageViewの上下左右反転

imgというUIImageViewをいじる場合、imgのtransformプロパティをアフィン変換のメソッドでいじってやればよろし。
以下の例は横軸の値をマイナスにすることで左右反転させている。
縦軸もマイナスにすれば上下左右に反転される。

img.transform = CGAffineTransformScale(img.transform, -1, 1)

なお、マイナスの数値は「現在表示されている状態を反転させる」という意味なので、反転前の状態に戻す時はもう一度マイナスの数値を与える。
プラスの数値を与えると正しい画像の向きに戻るというわけではない。
現在画像がどの向きで表示されているのかを、コードの中で把握しておく必要があるわけやね。

2015年10月19日月曜日

UIViewのアニメーション方法いろいろ

種類があるようなので、気づいたら追記する形でまとめていく。

UIView.beginAnimations()

beginAnimations()とcommitAnimations()ではさむタイプ
メソッド前にアニメ前の状態を設定しておき、Durationの秒数かけてbeginAnimationsとcommitAnimationsの間に書かれた(AnimationCurveやDurationは設定なので別として)状態にアニメーションする。
centerなどの位置や、alphaチャネルも変化できる。
print文はアニメが始まってすぐに表示される。

        image.center = CGPointMake(0, 0)

        UIView.beginAnimations("imageMove", context: nil)
        UIView.setAnimationCurve(UIViewAnimationCurve.Linear)
        UIView.setAnimationDuration(10.0)
        image.center = CGPointMake(-50, 100)
        UIView.commitAnimations()
        print("アニメ終わり")

UIView.animationWithDuration()

クロージャを使うタイプ
メソッド前にアニメ前の状態を設定しておき、Durationの秒数かけて最初のクロージャに書かれた状態にアニメーションする。
centerなどの位置や、alphaチャネルも変化できる。
print文はアニメが終了後に表示される。

        image.center = CGPointMake(0, 0)
        
        UIView.animateWithDuration(10.0,
            delay: 0,
            options: UIViewAnimationOptions.CurveLinear,
            animations: { () -> Void in
            self.image.center = CGPointMake(-50, 100)
            }) { (Bool) -> Void in
                print("アニメ終わり")

        }

UIImageViewのパラパラアニメ

各フレームのコマを配列に用意しておき、それをstartAnimating()で開始する。
RepeatCountは繰り返しの回数で、0の場合無限に繰り返し。
途中で終了する際はanimeImage.stopAnimating()。
終了後は先に設定しておいたUIImage(ここでは"normalImage")になる。
前述のUIViewのアニメーションと組み合わせ、パラパラアニメしながら位置や大きさを変化などもできる。

                //最初にアニメ終了後に表示するimageを設定しておく
                animeImage.image = UIImage(named: "normalImage")
                //アニメのコマ設定
                let imageArray:[UIImage] = [
                    UIImage(named: "animeImage1")!,
                    UIImage(named: "animeImage2")!,
                    UIImage(named: "animeImage3")!,
                    UIImage(named: "animeImage4")!
                ]
                animeImage.animationImages = imageArray
                animeImage.animationDuration = 2.0
                animeImage.animationRepeatCount = 1
                animeImage.startAnimating()

2015年10月16日金曜日

UIViewとかのトランジションアニメーション

画面上でImageViewとかをフェードイン/アウトとかさせる方法

その1:UIViewのアニメーション機能を使う

現在の状態からbeginAnimations()commitAnimations()の間に書かれた状態に変化させてくれるという、iOSではおなじみの方法。
最初にimageViewであるimage1のαチャネルの値(要するに透明度)を0(透明)にしておいて、setAnimationDurationで指定した時間(秒)をかけて、αチャネルの値を1(不透明)にする。
"fadeIn"はanimationIDということで、別の処理との識別に使うので、識別できればなんでもいいようだ。(この例では識別に使ってない)
setAnimationCurve()にアニメーションの進行速度の変化の指定もできる。ここでの.EaseOutはフェードインが速く始まりゆっくり終わる指定。

        image1.alpha = 0
        //フェードイン
        //アニメーションのタイプを指定
        UIView.beginAnimations("fadeIn", context: nil)
        //イージング指定
        UIView.setAnimationCurve(UIViewAnimationCurve.EaseOut)
        //アニメーション秒数を指定
        UIView.setAnimationDuration(2.0)
        //目標のアルファ値を指定
        image1.alpha = 1
        //アニメーション実行
        UIView.commitAnimations()

他にもsetAnimationDidStopSelector〜メソッドでアニメ実行終了後に呼ぶメソッドをSelectorとして指定できたりするようだ。
いろいろあるようなので、調べて使うよろし。

その2:QuartzCoreを使う

ついでに逆にフェードアウトも指定してみる。
その1のやり方でやってもいいんだけど、フェードアウトした直後にimage1をremoveFromSuperview()したところ、フェードアウトせずにさっさとimage1がremoveされてしまったので、別の方法を探したところでてきたのがこれ。
QuartzCoreFrameworkのインポートとかはプロジェクトの設定で必要なのかな。Objective-Cみたいにクラスごとにimportはいらないようだ。
beginAnimationsと違い、どこまでの範囲をアニメーションするとかはないようなので、必要であれば別メソッドに分けて実行させたほうがいいかも。さすがにメソッドの終わりで一区切りつくと思うので。

image1.alpha = 1
//フェードアウト
let transition = CATransition()
transition.duration = 2.0
transition.type = kCATransitionFade
view.layer.addAnimation(transition, forKey: nil)
image1.alpha = 0

なおこの場合、アニメーションが終わった後に
view.layer.removeAllAnimations()
としてアニメ設定を削除しておかないと、次回使う時に不具合を起こすことになるので注意だ。

その他のトランジションもパラメータを変えたりしてできるだろう。

2015年10月14日水曜日

Storyboardで作ったViewControllerをコードで表示

Storyboardで作ったViewContollerをSegueじゃなくコードから表示しようとして以下をやったんだけど、画面が真っ黒になってうまくいかない。
調べたところ、どうやらこれではStoryboardで作ったファイルと結びつかないSecondViewControllerクラスができるだけらしい。

    let vc = SecondViewController()
    self.presentViewController(vc, animated: true, completion: nil)


そこでこうしたらできた。
        let vc: SecondViewController = self.storyboard!.instantiateViewControllerWithIdentifier"SecondView" ) asSecondViewController
    self.presentViewController(vc, animated: true, completion: nil)

もしくは
    let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SecondView") as! SecondViewController
    self.presentViewController(vc, animated: true, completion: nil)

"SecondView"はStoryboardのIdentity InspectorのStoryboard IDにあらかじめ入力しておく。
下のコードで"Main"はStoryboardの名前。
通常Main.Storyboardって名前になってるので、拡張子を取ったMain。

これで晴れてStoryboardでグラフィカルなエディタで作ったViewControllerを表示できるのだね。
変数vcにはSecondViewControllerのプロパティやメソッドもあるので、それを操作してやることもできる。

むろん、画面上のインターフェース部品などをコードで全部書くつもりなら最初のやり方でもうまくいくと思う。

普段Segueばかり便利に使ってるから戸惑った。

Swiftでクラスのファイル名の変更

一度つけたクラス名のファイルを変更する場合、XcodeでProject Navigator(左側に出てるファイルの一覧が表示されてるアレだ)で当該のファイルを選び、File Inspector(通常右側に出てる、いろんな情報を表示してるあそこ)のIdentity and TypeのNameを変更してやればいい。

Objective-Cではコードの中に書かれたクラス名を右クリックしてRefactor > Rename...とかやるんだったと思った。
Swiftで同じことやると「RefactorはCとObjective-Cしか対応してないよ」って英文メッセージが出る。