Core Animationなどをポリポリ研究

  1. iAd Gallery風 Roll UI

    iAd GalleryというアプリがUS App Storeにあって、Tab -> BrowseがこういうUIになってます。

    このUIの利点はなんだろう、iAdだからリッチ感を出したくて普通のTableViewからひとひねりした、って感じでしょうか。あと、表示するのがバナーなので、TableViewで出すんじゃなくて、何か物体感を出したかったのかな、と思う。

    僕の実装は、UIScrollViewを無限スクロール可能にして、その上で見えている部分を半円として、各Cellの位置を計算しているだけ。

    円上の位置が決まると、sin,cosで中心からの高さと距離が分かるので、それでview.transformをセットして大きさを変える

    という感じ。

  2. [CATransaction flush]とは何か

    通常はRunLoopの終わりで勝手に呼ばれる。

    なので呼ぶ必要は無いんだけど、何かの事情でRunLoopがその後終了しないとき

    呼んであげると、アニメーションが始まる。

    たとえば、こんなコードで試せる。

    [CATransaction flush]を呼ばないとアニメーションしない。

    - (void)action
    {
        CABasicAnimation* animation;
        animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        animation.fromValue = [NSNumber numberWithFloat:1.0];
        animation.toValue = [NSNumber numberWithFloat:0.0];
        animation.duration = 2.0;
        [_layer addAnimation:animation forKey:nil];    
        
        //Call flush self!
        [CATransaction flush];    
        
        while (1) {
            //block current Run Loop
        }
    }
    

    あくまで、Current Run Loopなので外から

    [self performSelector:@selector(flush) withObject:nil afterDelay:1.0];
    
    - (void)flush
    {
        [CATransaction flush];
    }
    
    

    とかやってもダメ。

  3. kogumarecord:

but does it float - Definition: God is the shortest distance between zero and infinity

    kogumarecord:

    but does it float - Definition: God is the shortest distance between zero and infinity

  4. thinkupstudio:

nemoi:

udon13:

fukumatsu:


petapeta:


nsx:


kanmei:

maybowjing:

fukumatsu:

ssbt:

「聖フェニックス?」/「nori」のイラスト [pixiv]

    thinkupstudio:

    nemoi:

    udon13:

    fukumatsu:

    petapeta:

    nsx:

    kanmei:

    maybowjing:

    fukumatsu:

    ssbt:

    「聖フェニックス?」/「nori」のイラスト [pixiv]

  5. CAReplicatorLayerはSubLayerを.instance***にしたがってinstanceCount個copyして表示するLayer。
instance**は全部アニメーション可能なので、CAAnimationと組み合わせるととんでもないことになる。

以下、普通に複数表示すだけのコード。
.instanceTransformに画像のwidth右に動かすTransformを渡しているので、contentLayerが横に5個(4個コピーされて)表示される。
CALayer* contentLayer = [CALayer layer];
UIImage* image = [UIImage imageNamed:@"CA.jpg"];    
CGRect rect;
rect.origin = CGPointZero;
rect.size = image.size;
contentLayer.frame = rect;
contentLayer.contents = (id)image.CGImage;

CAReplicatorLayer* replicatorLayer = [CAReplicatorLayer layer];
replicatorLayer.frame = rect;
replicatorLayer.instanceCount = 5;

[replicatorLayer addSublayer:contentLayer];
[self.view.layer addSublayer:replicatorLayer];

CATransform3D transform;
transform = CATransform3DMakeTranslation(rect.size.width, 
                                         0,
                                         0);
replicatorLayer.instanceTransform = transform;

    CAReplicatorLayerはSubLayerを.instance***にしたがってinstanceCount個copyして表示するLayer。

    instance**は全部アニメーション可能なので、CAAnimationと組み合わせるととんでもないことになる。

    以下、普通に複数表示すだけのコード。

    .instanceTransformに画像のwidth右に動かすTransformを渡しているので、contentLayerが横に5個(4個コピーされて)表示される。

    CALayer* contentLayer = [CALayer layer];
    UIImage* image = [UIImage imageNamed:@"CA.jpg"];    
    CGRect rect;
    rect.origin = CGPointZero;
    rect.size = image.size;
    contentLayer.frame = rect;
    contentLayer.contents = (id)image.CGImage;
    
    CAReplicatorLayer* replicatorLayer = [CAReplicatorLayer layer];
    replicatorLayer.frame = rect;
    replicatorLayer.instanceCount = 5;
    
    [replicatorLayer addSublayer:contentLayer];
    [self.view.layer addSublayer:replicatorLayer];
    
    CATransform3D transform;
    transform = CATransform3DMakeTranslation(rect.size.width, 
                                             0,
                                             0);
    replicatorLayer.instanceTransform = transform;
    

  6.  .colorsはアニメーション可能なので

    こんなのができる。

    …
    
        [self performSelector:@selector(hoge:) withObject:gradientLayer afterDelay:1.0];
    
    }
    
    - (void)hoge:(CAGradientLayer*)gradientLayer
    
    {
    
        [CATransaction begin];
    
        [CATransaction setAnimationDuration:2.0];
    
        NSMutableArray* array = [NSMutableArray array];
    
        [array addObject:(id)[UIColor blueColor].CGColor];
    
        [array addObject:(id)[UIColor redColor].CGColor];
    
        gradientLayer.colors = array;
    
        [CATransaction commit];
    
    }
    

  7. CAGradientLayerのHello world!

- (void)viewDidLoad
{    
    CAGradientLayer* gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = self.view.bounds;
    gradientLayer.startPoint = CGPointZero;
    gradientLayer.endPoint = CGPointMake(1.0, 1.0);
    NSMutableArray* array = [NSMutableArray array];
    [array addObject:(id)[UIColor redColor].CGColor];
    [array addObject:(id)[UIColor blueColor].CGColor];
    gradientLayer.colors = array;
    [self.view.layer addSublayer:gradientLayer];
}

    CAGradientLayerのHello world!

    - (void)viewDidLoad

    {    

        CAGradientLayer* gradientLayer = [CAGradientLayer layer];

        gradientLayer.frame = self.view.bounds;

        gradientLayer.startPoint = CGPointZero;

        gradientLayer.endPoint = CGPointMake(1.0, 1.0);

        NSMutableArray* array = [NSMutableArray array];

        [array addObject:(id)[UIColor redColor].CGColor];

        [array addObject:(id)[UIColor blueColor].CGColor];

        gradientLayer.colors = array;

        [self.view.layer addSublayer:gradientLayer];

    }

  8. CARenderer

    OS Xのみしか無いCARenderer、iOSでもUndocument Classだけど存在してて

    OpenGLの世界と繋げるClassなので、EAGLContextを使うようになってる。

    + (id)rendererWithEAGLContext:(id)fp8 options:(id)fp12;

    OS Xのイニシャライズメソッドはこれ

    + (CARenderer *)rendererWithCGLContext:(void *)ctx options:(NSDictionary *)dict;

  9. Animatable UIView properties

    UIViewのPropertyのいくつかはアニメーション可能

    http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html

    Animatable UIView properties

    に書いてある

    だがしかし、それだけではなくて

    UIScrollViewのcontentOffsetも

    - (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated

    があるように、アニメーションできる。

    ということは、ドキュメントには書いてないけど

    UIScrollViewのcontentOffsetはAnimatable Propertyである。

    ので、

        [UIView beginAnimations:nil context:NULL];

        [UIView setAnimationDuration:10];

        [scrollView setContentOffset:CGPointMake(0, 500)];

        [UIView commitAnimations];

    とやると、10秒でスクロールする。

    たぶん、animatedという引数があるやつは全部この方法でアニメーション時間や、Timing Function(アニメーションのカーブ)が変更できる。



  10. UIScrollViewとCAScrollViewは友達か?

    どうも違うみたい。要継続調査

    (この調査がなんの役に立つというのだろう)

  11. CAScrollLayer »

    CAScrollLayerは、上に乗っけてるSubLayerをスクロールさせるLayer。

    CAScrollLayer.contentsがスクロールするわけではない!

    UIScrollViewみたいにバウンドするアニメーションを提供してくれるわけではないので、ちょいと使いづらいかなぁ。逆に言えばCAKeyframeAnimationを使って、設定してあげれば自分でバウンドが作れる。

    と思ったけど

    - (void)scrollToPoint:(CGPoint)p;

    しかないので、それたぶん無理。


  12. Core Animationはかなり謎が多いことが予想されるけど、CABasicAnimationの + (id)defaultValueForKey:(NSString *)key

    のkeyに見たことが無いのが来るのが判明して、上書きしたら面白いことになった。

    keyがframeIntervalのとき、[NSNumber numberWithFloat:1.0/10]って返すと、フレームレートが10になる。フェードだとカクカクフェードアウトする

  13. 影を付けるとこうなる。
影を使う場合、光がどこか差しているのか、を考えないと不自然になる。
拡大したときは、カードが上に上がるのだがら影も変わるのだ

    影を付けるとこうなる。

    影を使う場合、光がどこか差しているのか、を考えないと不自然になる。

    拡大したときは、カードが上に上がるのだがら影も変わるのだ

Theme = Manuscript Neue