kobold2d v2.1.0 Xcode5対応

記事にするのが遅れましたが、kobold2d v2.1.0をxcode5で使用可能にするパッチが、作者から出ています。


対応が切られたと思っていましたが、対応してくれました。ありがたく使わせてもらいましょう。

-performSelector:withObject:afterDelay:を用いて、複数のアニメーションを実行するときの注意点

今回ははまった。

なので共有として書いておく


以下のようなコードを書いていた

[self performSelector:@selector(animate1) withObject:nil afterDelay:0.5f];
[self animate2];
[self performSelector:@selector(animate3) withObject:nil afterDelay:0.5f];


animate1~3は内部でUIViewのアニメーションを実行するメソッドが書かれており、durationは全て0.5fである。


これを書いたとき、以下のようにアニメーションされる事を期待した。

  1. animate2が実行される
  2. animate2の終了直後、”同時に”animate1とanimate3が実行される


だが、実際は以下のように動作した。

  1. animate2が実行される
  2. . animate1が実行される
  3. 2.からほんの少しだけ遅れてanimate3が実行される

[self animate2]の実行により、内部の時計が少しだけ進んでしまった事に依るanimate3の遅延だと考えられる。

今回はいくつかのファイルにまたがってこのような記述を行ったため、completion^()を使うのをさけてしまった。
出来るだけcompletionを使う実装を心がけたい。

iOSでEasing

iOSとくにUIKitを使っている場合、デフォルトではイージングが4種類しかありません。

そこでおすすめなのが以下のイージングライブラリです。
https://github.com/bryanoltman/CAAnimation-EasingEquations:CAAnimation-EasingEquations

準備

  1. QuartzCoreフレームワークをプロジェクトにリンクする
  2. CAAnimation+EasingEquations.h/m を追加
  3. イージングを使用したいファイルに上記ヘッダーをインポートする

使い方

CAAnimationを使用しているので、UIViewではなくCALayerをターゲットにします。
http://easings.net/jaここにのっているイージングを使用可能です。

具体的な使用方法は以下の通り

CALayerのプロパティをキーとする
    [CAAnimation addAnimationToLayer:animatedView.layer
                         withKeyPath:@"opacity"
                            duration:1
                                  to:0
                      easingFunction:CAAnimationEasingFuctionEaseInBounce];
CATransform3Dを使用する
    CATransform3D tr;
    tr = CATransform3DMakeScale(2.5, 2.5, 1.0);
    tr = CATransform3DTranslate(tr, 95, 0, 0);
    [CAAnimation addAnimationToLayer:animatedView.layer
                            duration:1
                           transform:tr
                      easingFunction:CAAnimationEasingFuctionEaseOutBack];


非常に簡単に使用出来るので、UIKitのイージングに不満を持っているようでしたら是非。
AppleさんEasingくらいさっさと追加してくれればいいのに…)

ARC環境におけるNSTimerの再利用(再起動)

NSTimerは -invalidate メソッドをコールするとARCによって回収されてしまう。
なので、再起動のためには再度タイマーの内容を決定してやる必要がある。


具体的な方法を示す。

適当なところで、NSTimer *timerのインスタンスを確保しておく。
そして、以下のようにメソッドを実装。

タイマーを起動するときは -startUpdate、タイマーを終了するときは -stopUpdateを呼んでやれば良い。

-(void)update:(NSTimer*)currentTimer
{
     // update
}


-(void)startUpdate
{
    timer = nil;
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0f/60.0f
                                                                      target:self
                                                                   selector:@selector(update:)
                                                                   userInfo:nil
                                                                    repeats:YES];
    [timer fire];
}
-(void)stopUpdate
{
    [timer invalidate];
}

UIScrollView に背景画像を設定する

#import <UIKit/UIKit.h>
@interface UIScrollViewWithBGImage : UIViewController <UIScrollViewDelegate>
{
    UIImageView *backgroundImageView;
}

@property (nonatomic, retain) UIScrollView *scrollView;

@end

上のようなヘッダーにおいて、scrollViewプロパティに背景画像を追加する事を考える。

その1

簡単なのは、viewをaddした後に、次のように呼ぶこと。

     [self.view bringSubviewToFront:_scrollView];
     for(UIView *subview in [_scrollView subviews])
     {
          [_scrollView bringSubviewToFront:subview];
     }

ただこの方法だと、viewがたくさんあったときに、最後にほぼ全てのviewのz-indexを調整しなくてはならなくなる。

ということで

その2

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view./* initialize */    
    [self.view addSubview:_scrollView];
    [_scrollView addSubview:backgroundImageView];
}

#pragma mark -
#pragma mark UIScrollView delegate
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGRect scrolledRect;
    scrolledRect.origin = CGPointMake(_scrollView.contentOffset.x, _scrollView.contentOffset.y);
    scrolledRect.size = backgroundImageView.frame.size;
    backgroundImageView.frame = scrolledRect;
}

こんな感じで実装する。scrollViewのdelegateを使って、bgImageViewのoriginを逐一変更する。
どこにでもあるコードだと思うけども、一応。


今度UIScrollViewのプロパティに関してまとめるかも?
いろいろ忘れるときがあるので。