iOS   发布时间:2022-03-30  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了iphone – 动画CAShapeLayer Pie大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用CAShapeLayer创建一个简单的动画饼图.我想让它从0动画到提供的百分比.

要创建形状图层,我使用:

CGMutablePathRef piePath = CGPathCreateMutable();
CGPathMoveToPoint(piePath,NULL,self.frame.size.width/2,self.frame.size.height/2);
CGPathAddLineToPoint(piePath,0);
CGPathAddArc(piePath,self.frame.size.height/2,radius,degrees_TO_radians(-90),0);        
CGPathAddLineToPoint(piePath,self.frame.size.width/2 + radius * cos(degrees_TO_radians(-90)),self.frame.size.height/2 + radius * sin(degrees_TO_radians(-90)));

pie = [CAShapeLayer layer];
pie.fillColor = [UIColor redColor].CGColor;
pie.path = piePath;

[self.layer addSublayer:pie];

然后动画我用:

CGMutablePathRef newPiePath = CGPathCreateMutable();
CGPathAddLineToPoint(newPiePath,0);    
CGPathMoveToPoint(newPiePath,self.frame.size.height/2);
CGPathAddArc(newPiePath,degrees_TO_radians(125),0);                
CGPathAddLineToPoint(newPiePath,self.frame.size.width/2 + radius * cos(degrees_TO_radians(125)),self.frame.size.height/2 + radius * sin(degrees_TO_radians(125)));    

CABasicAnimation *pieAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pieAnimation.duration = 1.0;
pieAnimation.removedOnCompletion = NO;
pieAnimation.fillmode = kCAFillmodeForWARDs;
pieAnimation.fromValue = pie.path;
pieAnimation.toValue = newPiePath;

[pie addAnimation:pieAnimation forKey:@"animatePath"];

显然,这是以一种非常奇怪的方式制作动画.形状只是成长为最终状态.有没有一种简单的方法可以让这个动画跟随圆圈的方向?或者这是CAShapeLayer动画的限制?

解决方法

我知道这个问题早已得到解答,但我不认为这是CAShapeLayer和CAKeyframeAnimation的好例子. Core Animation有能力为我们做动画补间.这是一个类(包含UIView,如果你喜欢),我用它来很好地完成效果.

图层子类为progress属性启用隐式动画,但视图类将其setter包装在UIView动画方法中.使用带有UIViewAnimationOptionBeginFromCurrentState的0.0长度动画的有趣(并且最终有用)副作用是每个动画取消前一个动画,导致平滑,快速,高帧率的饼图,如this(动画)和this(不动画,但递增).

DZRoundProgre@R_262_11237@iew.h

@interface DZRoundProgressLayer : CALayer

@property (nonatomiC) CGFloat progress;

@end

@interface DZRoundProgre@R_262_11237@iew : UIView

@property (nonatomiC) CGFloat progress;

@end

DZRoundProgre@R_262_11237@iew.m

#import "DZRoundProgre@R_262_11237@iew.h"
#import <QuartzCore/QuartzCore.h>

@implementation DZRoundProgressLayer

// Using Core Animation's generated properties allows
// it to do tweening for us.
@dynamic progress;

// This is the core of what does animation for us. It
// tells CoreAnimation that it needs to redisplay on
// each new value of progress,including tweened ones.
+ (BOOL)needsDisplayForKey:(NSString *)key {
    return [key isEqualToString:@"progress"] || [super needsDisplayForKey:key];
}

// This is the other crucial half to tweening.
// The animation we return is compatible with that
// used by UIView,but it also enables implicit
// filling-up-the-pie animations.
- (id)actionForKey:(NSString *) aKey {
    if ([aKey isEqualToString:@"progress"]) {
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:aKey];
        animation.fromValue = [self.presentationLayer valueForKey:aKey];
        return animation;
    }
    return [super actionForKey:aKey];
}

// This is the gold; the drawing of the pie itself.
// In this code,it draws in a "HUD"-y style,using
// the same color to fill as the border.
- (void)drawInContext:(CGContextRef)context {
    CGRect circleRect = CGRecTinset(self.bounds,1,1);

    CGColorRef borderColor = [[UIColor whiteColor] CGColor];
    CGColorRef BACkgroundColor = [[UIColor colorWithWhite: 1.0 alpha: 0.15] CGColor];

    CGContextSetFillColorWithColor(context,BACkgroundColor);
    CGContextSetstrokeColorWithColor(context,borderColor);
    CGContextSetLineWidth(context,2.0f);

    CGContextFillEllipseInRect(context,circleRect);
    CGContextstrokeEllipseInRect(context,circleRect);

    CGFloat radius = MIN(CGRectGetMidX(circleRect),CGRectGetMidY(circleRect));
    CGPoint center = CGPointMake(radius,CGRectGetMidY(circleRect));
    CGFloat startAngle = -M_PI / 2;
    CGFloat endAngle = self.progress * 2 * M_PI + startAngle;
    CGContextSetFillColorWithColor(context,borderColor);
    CGContextMoveToPoint(context,center.x,center.y);
    CGContextAddArc(context,center.y,startAngle,endAngle,0);
    CGContextClosePath(context);
    CGContextFillPath(context);

    [super drawInContext:context];
}

@end

@implementation DZRoundProgre@R_262_11237@iew
+ (Class)layerClass {
    return [DZRoundProgressLayer class];
}

- (id)init {
    return [self initWithFrame:CGRectMake(0.0f,0.0f,37.0f,37.0f)];
}

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        self.opaque = NO;
        self.layer.contentsScale = [[UIScreen mainScreen] scale];
        [self.layer setNeedsDisplay];
    }
    return self;
}

- (void)setProgress:(CGFloat)progress {
    [(id)self.layer setProgress:progress];
}

- (CGFloat)progress {
    return [(id)self.layer progress];
}

@end

大佬总结

以上是大佬教程为你收集整理的iphone – 动画CAShapeLayer Pie全部内容,希望文章能够帮你解决iphone – 动画CAShapeLayer Pie所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。