关于NSImageView视图360度旋转动画在Mac OS 10.13版本失效问题的解析方案

笔者之前上线的一款 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


果然点击开始动画旋转后不再漂移,看似正常,由衷佩服老外,效果如图:




不过新的问题出现了,当选择另一个频道,也就是重新开始动画,发现位置又偏移了,如下图:




这个问题老外朋友demohttps://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

发布了71 篇原创文章 · 获赞 51 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/mapboo/article/details/81039811