为什么我的 CATransaction 不遵守我设置的持续时间?
我正在将 iPhone 应用程序移植到 Mac OS X。此代码已在 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: 正在工作,因为该块在动画完成时正在执行。
我在这里做错了什么?
I'm porting an iPhone app to Mac OS X. This code was being used successfully on the 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];
}
The Mac version uses CATransaction to group the animations, like so:
- (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];
}
The animation is executing fine, except that the duration is 1.0 seconds. I can change the setAnimationDuration: call to anything, or omit it completely, and still the animation is 1.0 seconds in duration, every time. I also don't think the setAnimationTimingFunction: call is doing anything. However, setCompletionBlock: is working, because that block is executing when the animation completes.
What am I doing wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果我没记错的话,你不能使用 CoreAnimation 直接对 NSView 进行动画处理。为此,您需要 NSAnimationContext 和 [NSView animator]。 CATransaction 仅适用于 CALayers。
If I am not mistaken you cannot use CoreAnimation to animate NSView's directly. For that you need NSAnimationContext and [NSView animator]. CATransaction will only work with CALayers.
它没有准确回答问题,但我最终使用 NSAnimationContext 而不是 CATransaction。
这是可行的,但我对此并不是很高兴。主要是,NSAnimationContext 没有像 CATransaction 那样的回调完成机制,因此我必须将其放在那里以显式获取视图的动画并设置委托,以便触发回调。问题是,每个动画都会多次触发它。事实证明,这对我正在做的事情没有任何不良影响,只是感觉不对。
这是可行的,但如果有人知道更好的解决方案,我仍然想要一个。
It doesn't answer the question exactly, but I ended up using NSAnimationContext instead of CATransaction.
It's works, but I'm not terribly happy about it. Mainly, NSAnimationContext doesn't have a callback completion mechanism like CATransaction does, so I had to put the thing there to explicitly get the view's animation and set the delegate so a callback gets triggered. Problem with that is, it gets triggered multiple times for each animation. This turns out to have no ill effects for what I'm doing, it just feels wrong.
This is workable, but if anyone knows a better solution, I'd still like one.