笔者之前上线的一款 Mac App 在电脑升级系统10.13之后,发现一个诡异的现象,视图360度旋转失控了,这里记录下问题解决办法,毕竟问题还是有点棘手;
升级10.13之前正常的旋转代码如下:
#pragma mark- animation
- (void)rotation{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI/2 , 0, 0, 1)];
animation.duration = 10;
animation.cumulative = YES;
animation.repeatCount = INT_MAX;
[self.redioRollView.layer addAnimation:animation forKey:@"animation"];
}
-(void)stopAllAnimations{
[self.redioRollView.layer removeAllAnimations];
}
升级10.13之后,旋转出现诡异现象,如下图:
无可奈何花落去,只能着手更新版本解决问题了,初步判断应该是旋转中心点失效了,可行办法就是重新初始化,一番度娘发现,同样问题出现,问题地址:http://www.cocoachina.com/bbs/read.php?tid-1728771.html (笔者已回复),可行只有问题,没有答案,毕竟国内开发Mac App的屈指可数,只能借助overflow了,果然有大牛找到问题,和笔者预判差不多,不多说,直接发链接:
https://stackoverflow.com/questions/46871076/rotate-nsimageview-at-its-center-to-make-it-spin
https://stackoverflow.com/questions/25247816/how-to-animate-a-rotation-with-nsimageview
果然点击开始动画旋转后不再漂移,看似正常,由衷佩服老外,效果如图:
不过新的问题出现了,当选择另一个频道,也就是重新开始动画,发现位置又偏移了,如下图:
这个问题老外朋友demo(https://github.com/bansalvks/Mac-Dummies)也同样出现,如下图:
其实这个问题也好解决,那就是每次开始重新旋转动画时,先初始化到最初的位置即可,如代码:
//圆形
self.redioRollView.image = [NSImage imageNamed:@"icon-1024-mac"];
self.redioRollView.wantsLayer = YES;
self.redioRollView.layer.cornerRadius = 79;
self.redioRollView.layer.masksToBounds = YES;
self.redioRollView.layer.borderWidth = .1;
self.redioRollView.layer.borderColor = [[NSColor yellowColor] CGColor];
self.redioRollView.layer.shouldRasterize = YES;
initRollPoint = self.redioRollView.layer.position; //记住最初的位置
问题顺利解决,核心代码如下:
#pragma mark- animation
- (void)rotation{
self.redioRollView.layer.position = initRollPoint;
[self.redioRollView setAnchorPoint:CGPointMake(0.5, 0.5)];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI/2 , 0, 0, 1)];
animation.duration = 10;
animation.cumulative = YES;
animation.repeatCount = INT_MAX;
[self.redioRollView.layer addAnimation:animation forKey:@"animation"];
}
-(void)stopAllAnimations{
[self.redioRollView.layer removeAllAnimations];
}
一个category类,方便调用,代码文件如下:
#import <Cocoa/Cocoa.h>
@interface NSView (AnchorPoint)
-(void)setAnchorPoint:(CGPoint)anchorPoint;
@end
#import "NSView+AnchorPoint.h"
@implementation NSView (AnchorPoint)
-(void)setAnchorPoint:(CGPoint)anchorPoint{
self.layer.anchorPoint = anchorPoint;
CGRect frame = self.layer.frame;
float xCoord = frame.origin.x + frame.size.width;
float yCoord = frame.origin.y + frame.size.height;
CGPoint point = CGPointMake(xCoord, yCoord);
self.layer.position = point;
}
@end
最后,欢迎大家体验这款收音机Mac App:时光FM。