我们想在我们的iPhone应用程序中使用UITabBar,但有一个例外:我们有一个“同步”按钮,我想在同步操作发生时旋转 .
不幸的是,这意味着必须创建一个自定义标签栏,但这既不在这里也不在那里:我使用Core Animation实现的动画看起来很棒 . 问题是,在制作动画时,它会对屏幕上使用动画的其他所有内容产生不利影响:UITableView滚动,MKMapView平移和引脚丢弃等 . 我的测试设备是iPhone 4 .
问题似乎是我如何've implemented the tab bar - I wanted to achieve something very similar to UITabBar, where you just supply a PNG for the icon and it uses the alpha channel to create the normal and highlighted states by masking a background image. I accomplished this with CALayer' s mask
属性:
// Inside a UIView subclass' init method...
// Create the mask layer by settings its contents as our PNG icon.
CALayer *maskLayer = [CALayer layer];
maskLayer.frame = CGRectMake(0, 0, 31, 31);
maskLayer.contentsGravity = kCAGravityCenter;
maskLayer.contentsScale = [[UIScreen mainScreen] scale];
maskLayer.rasterizationScale = [[UIScreen mainScreen] scale];
maskLayer.contents = (id)symbolImage.CGImage;
maskLayer.shouldRasterize = YES;
maskLayer.opaque = YES;
fgLayer = [[CALayer layer] retain];
fgLayer.frame = self.layer.frame;
fgLayer.backgroundColor = [UIColor colorWithImageNamed:@"tabbar-normal-bg.png"].CGColor;
fgLayer.mask = maskLayer; // Apply the mask
fgLayer.shouldRasterize = YES;
fgLayer.opaque = YES;
[self.layer addSublayer:fgLayer];
(注意:在上面的屏幕截图中你可以看到我还添加了一个阴影层,但为了简单起见,我从代码中删除了它 . 我在动画时从同步图标中删除阴影层,所以它不应该是相关的 . )
要设置动画,我只需旋转遮罩层:
- (void)startAnimating {
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath: @"transform"];
CATransform3D transform = CATransform3DMakeRotation(RADIANS(179.9), 0.0, 0.0, 1.0);
animation.toValue = [NSValue valueWithCATransform3D:transform];
animation.duration = 5;
animation.repeatCount = 10000;
animation.removedOnCompletion = YES;
[fgLayer.mask addAnimation:animation forKey:@"rotate"]; // Add animation to the mask
}
所以这一切都很有效,除了性能 . 你可以看到我已经尝试过关于栅格化图层/使它们变得不透明的技巧,但是没有帮助 .
我想我已经确定掩模层是罪魁祸首 . 当我取出遮罩层并只旋转 fgLayer
而不是它的遮罩时,性能非常好,尽管它是's certainly not the affect I' m:
如果在应用蒙版时旋转 fgLayer
而不是蒙版,性能也和以前一样糟糕 .
因此,如果必须重新组合掩模,动画的每一帧都变慢,是否还有其他技术可以用来实现类似的效果,从而获得更好的性能?使用路径而不是图像作为遮罩层?或者我将不得不下载OpenGL或其他什么来获得良好的性能?
UPDATE: 进一步强化了面具减速的想法,我的同事建议尝试用图像作为内容来旋转CALayer - 这与上面没有面具的例子类似 - 而且表现也很好 . 所以我真的只能做那样的纯色(没有渐变),但它可能是一个很好的临时解决方案 . 我仍然喜欢旋转具有良好性能的面膜,所以建议欢迎:)
2 回答
布伦特,
为什么需要使用图层蒙版?你不能只是将你的掩码层转换为子层吗?您只需要确保您的图像具有正确的alpha,并且您将使用它的CGImageRef作为该图层的内容 .
另一件事 . 我还没弄清楚为什么会这样,但是当我在每一层上应用shouldRasterize而不仅仅是顶层时,我也注意到了性能问题 . 您可能会看到在掩码图层中删除对setShouldRasterize:YES的引用是否有帮助 .
一种方法是创建一个
CAShapeLayer
用作你的面具 - 你要确保旋转是性能问题的来源 - 它很可能是导致大部分延迟的屏蔽,在这种情况下你会做了所有那些矢量化的好处 .我认为最好的解决方案是使用
UIImage
的动画功能:创建图标旋转动画的每一帧的幻灯片,并在标签栏中显示动画UIImage
. 这不是最优雅的解决方案,但系统中的一些动画 - 邮件和便笺垃圾 - 可以“删除”图标和各种形式的活动指示器 - 例如 - 以相同的方式实现 .