5

iPhoneアプリをMacOSXに移植しています。このコードは、iPhoneで正常に使用されていました。

- (void) moveTiles:(NSArray*)tilesToMove {
    [UIView beginAnimations:@"tileMovement" context:nil];
    [UIView setAnimationDuration:0.1];  
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(tilesStoppedMoving:finished:context:)];

    for( NSNumber* aNumber in tilesToMove ) {
        int tileNumber = [aNumber intValue];
        UIView* aView = [self viewWithTag:tileNumber];
        aView.frame = [self makeRectForTile:tileNumber];
    }

    [UIView commitAnimations];
}

Macバージョンでは、次のようにCATransactionを使用してアニメーションをグループ化します。

- (void) moveTiles:(NSArray*)tilesToMove {
    [CATransaction begin];
    [CATransaction setAnimationDuration:0.1];
    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    [CATransaction setCompletionBlock:^{
        [gameDelegate tilesMoved];
    }];

    for( NSNumber* aNumber in tilesToMove ) {
        int tileNumber = [aNumber intValue];
        NSView* aView = [self viewWithTag:tileNumber];
        [[aView animator] setFrame:[self makeRectForTile:tileNumber]];
    }

    [CATransaction commit];
}

アニメーションは、継続時間が1.0秒であることを除いて、正常に実行されています。setAnimationDurationを変更できます。何かを呼び出すか、完全に省略しても、アニメーションの継続時間は毎回1.0秒です。また、setAnimationTimingFunction:呼び出しは何もしていないと思います。ただし、setCompletionBlock:は機能しています。これは、アニメーションの完了時にそのブロックが実行されているためです。

私はここで何が間違っているのですか?

4

2 に答える 2

5

私が間違っていなければ、CoreAnimationを使用してNSViewを直接アニメーション化することはできません。そのためには、NSAnimationContextと[NSViewアニメーター]が必要です。CATransactionは、CALayersでのみ機能します。

于 2010-11-09T07:43:49.653 に答える
2

質問に正確に答えることはできませんが、CATransactionの代わりにNSAnimationContextを使用することになりました。

- (void) moveTiles:(NSArray*)tilesToMove {
    [NSAnimationContext beginGrouping];
    [[NSAnimationContext currentContext] setDuration:0.1f];

    for( NSNumber* aNumber in tilesToMove ) {
        int tileNumber = [aNumber intValue];
        NSView* aView = [self viewWithTag:tileNumber];
        [[aView animator] setFrame:[self makeRectForTile:tileNumber]];

        CAAnimation *animation = [aView animationForKey:@"frameOrigin"];
        animation.delegate = self;
    }

    [NSAnimationContext endGrouping];
}

それはうまくいきますが、私はそれについてひどく満足していません。主に、NSAnimationContextにはCATransactionのようなコールバック完了メカニズムがないため、ビューのアニメーションを明示的に取得し、コールバックがトリガーされるようにデリゲートを設定するために、そこに物を置く必要がありました。それに関する問題は、アニメーションごとに複数回トリガーされることです。これは私がしていることに悪影響を及ぼさないことが判明しました、それはただ間違っていると感じます。

これは実行可能ですが、誰かがより良い解決策を知っているなら、私はまだそれを望んでいます。

于 2010-11-09T07:19:42.590 に答える