Yadokari Lab

篭ってなんか作ってます

UIView animateWith...の逐次実行

UIKit標準のAPIでは次のようなBlock構文でアニメーションが実行出来る

[UIView animateWithDuration:1.0f //アニメーションの期間
                      delay:0.5f //アニメーションの開始時刻
                    options:UIViewAnimationOptionCurveEaseIn //アニメーションの設定
                 animations:^{
                            //アニメーションの位置とかの設定
               } completion:^(BOOL finished) {
                            //アニメーション後の処理
               }];
                     

あるアニメーションが終わった直後、次のアニメーションを実行したいときは次のように別のメソッドを終了時に実行するというのはわりとよくやる

- (void) firstAnimation{
    [UIView animateWithDuration:1.0f //アニメーションの期間
                          delay:0.5f //アニメーションの開始時刻
                        options:UIViewAnimationOptionCurveEaseIn //アニメーションの設定
                     animations:^{
                                //アニメーションの位置とかの設定
                   } completion:^(BOOL finished) {
                                [self secondAnimation];
                   }];
}

- (void) secondAnimation{
    [UIView animateWithDuration:1.0f //アニメーションの期間
                          delay:0.5f //アニメーションの開始時刻
                        options:UIViewAnimationOptionCurveEaseIn //アニメーションの設定
                     animations:^{
                                //アニメーションの位置とかの設定
                   } completion:^(BOOL finished) {
                                
                   }];
}

もちろん最初のメソッドのcompletionブロックのなかに直接[UIView animateWithDuration:...を書いてあげてもいいけれど、個人的にはインデントが深くなりすぎるので嫌である。 と、ここまでは普通のはなし。今回紹介する逐次実行の実装方法はキーフレームオブジェクトを導入して一つのメソッドのみで簡潔(?)に処理できる。

キーフレームオブジェクトでは@property宣言に(copy)でブロック変数を渡していることに注意する。UIViewカテゴリ拡張でstaticメソッドで通常のAPIライクに処理できる。 実装例:

//ExampleViewController.h
#import <UIKit/UIKit.h>
#import "UIView+CustomAnimation.h"

@interface ExampleViewController : UIViewController

@end

//ExampleViewController.m

@interface ExampleViewController ()

@end

@implementation ExampleViewController

- (void)viewWillAppear:(BOOL)animated {
    self.view.alpha = 0.0f;
    self.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001f, 0.001f);
    [UIView commitAnimationKeyFrames:
         [NSArray arrayWithObjects:
          [AnimationKeyFrame keyFrameWithDulation:0.5f
                                            Delay:0.05f
                                          Options:UIViewAnimationOptionCurveEaseIn
                                        Animation:^{
                                            self.view.alpha = 0.2f;
                                            self.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.2f, 0.2f);
                                        }],
          [AnimationKeyFrame keyFrameWithDulation:0.2f
                                            Delay:0.0f
                                          Options:UIViewAnimationOptionCurveEaseIn
                                        Animation:^{
                                            self.view.alpha = 1.0f;
                                            self.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0f, 1.0f);
                                        }], nil]
                            OnCompletion:^(BOOL finished) {}];
}

@end

ExampleViewControllerに途中で速度を変えて遠方から登場するエフェクトがかかる。

 

参考URL: How to store blocks in properties in Objective-C?

http://stackoverflow.com/questions/4081831/how-to-store-blocks-in-properties-in-objective-c

NSArrayの for in loop をメソッドで代用する

普段あまりにもNSArrayでfor inを多用していて、中にif文が入ったりすると少し個人的に嫌なのでfor in loopをメソッドで代用してみた

これを用いれば

NSArray* arr = [NSArray arrayWithObjects:@"eee",@"dd",@"hoge",@"elem", nil];

for (id elem in arr) {
    if ([elem hasPrefix:@"e"]) {
        NSLog(@"%@",elem);
    }
}

と要素を取り出す処理と内部処理がごっちゃになっているところを

NSArray* arr = [NSArray arrayWithObjects:@"eee",@"dd",@"hoge",@"elem", nil];

functionForElementBlock filter =
^(id elem){ if([elem hasPrefix:@"e"]) NSLog(@"%@",elem);};

[arr commitFunctionForElements:filter];

のように分離できる。

 

参考サイト:Objective-Cのブロック構文をメソッドの引数にする

http://d.akiroom.com/2011-11/objective-c-blocks-method-argument/

GHCi runtime linker: fatal error: I found a duplicate definition for symbol 出現時のメモ

Yesodで久々に新しいプロジェクトを立ち上げようとしたら次のような実行時エラーが出た。(Mac mini 2012, mountain lion)



GHCi runtime linker: fatal error: I found a duplicate definition for symbol
_fps_count
whilst processing object file
/Users/***/Library/Haskell/ghc-7.4.2/lib/bytestring-0.10.0.2/lib/HSbytestring-0.10.0.2.o
This could be caused by:
* Loading two different object files which export the same symbol
* Specifying the same object file twice on the GHCi command line
* An incorrect `package.conf' entry, causing some object to be
loaded twice.
GHCi cannot safely continue in this situation. Exiting now. Sorry.

いろいろとcabal installでパッケージ入れすぎたか…ひとまずbytestringパッケージの多重定義エラーくさいのでghcのパッケージをひと通り洗い出す



   $ ghc-pkg list
   /Library/Frameworks/GHC.framework/Versions/7.4.2-i386/usr/lib/ghc-7.4.2/package.conf.d
   中略
   bytestring-0.9.2.1
   中略
   /Users/***/.ghc/i386-darwin-7.4.2/package.conf.d
   中略
   bytestring-0.10.0.2
   中略


/Library/Frameworks/GHC.framework/Versions/7.4.2-i386/usr/lib/ghc-7.4.2/package.conf.d 配下のbytestring-0.9.2.1を移動して再度試す



cabal: Could not resolve dependencies:
trying: tumblrclient-0.0.0
rejecting: aeson-0.6.1.0/installed-ed3... (package is broken)
trying: aeson-0.6.1.0
trying: unordered-containers-0.2.3.0/installed-cc1...
rejecting: hashable-1.2.0.5/installed-616..., 1.1.2.5/installed-867...
(package is broken)
rejecting: hashable-1.2.0.5, 1.2.0.4, 1.2.0.3, 1.2.0.2, 1.2.0.1, 1.2.0.0,
1.1.2.5, 1.1.2.4, 1.1.2.3, 1.1.2.2, 1.1.2.1, 1.1.2.0, 1.1.1.0, 1.1.0.0,
1.0.1.1, 1.0.1.0, 1.0.0 (conflict: unordered-containers =>
hashable==1.1.2.5/installed-867...)

なんかダメっぽい。また元に戻して今度は/Users/***/.ghc/i386-darwin-7.4.2/package.conf.d配下のbytestring-0.10.0.2を移動して再度cabal install && yesod devel



Yesod devel server. Press ENTER to quit
Configuring tumblrclient-0.0.0...
Rebuilding application... (using Cabal library)
Starting development server...
Starting devel application
Devel application launched: http://localhost:3000

なんとか治ったっぽい?

 

参考サイト: runhaskell error on ghc7.02

http://stackoverflow.com/questions/5388894/runhaskell-error-on-ghc7-02

UIButtonの見た目をクロスフェードする

クロスフェードのやり方はググれば他にも割りと出てきます。

この方法だと使ったUIImageViewをメソッド内でスッキリと開放できるのが気持ちいいです。

transitionWithViewメソッドの中のオプションについては

UIViewクラス | Second Flush

http://secondflush2.blog.fc2.com/blog-entry-942.html#UIViewAnimationOptions

に詳しいです。