沿路径iOS移动两个形状?

时间:2013-06-06 17:42:52

标签: iphone ios graphics uiview

我是Objective-C的新手,我正在尝试创建一个iPhone应用程序。我试图沿着一条路径移动两个矩形(沿着彼此后面标记)(特别是一个斜直的椭圆形)。

使用下面的代码,我可以显示两个矩形,但问题是当我更改单独动画的起点值时,其中一个矩形最终会追上另一个矩形在动画结束时..我该如何解决这个问题?

同样,我想沿着自定义路径(轨道)移动两个形状,并且两个对象/形状必须彼此分开,并且在整个动画中相隔不同的距离。

我的代码如下:

#import "track.h"
#import <QuartzCore/QuartzCore.h>

#define degreesToRadian(x) (M_PI * x / 180.0)
#define radiansToDegrees(x) (x * 180 / M_PI);


@implementation track

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    //call three methods once class is istantiated
    //pass parameters for UIView, width, color, size, points (start, end)
    [self drawTrack];
    [self animateFirstRunner];
    [self animateSecondRunner];

}

- (void) animateFirstRunner
{
    //create an animation and give it certain specs
        CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        pathAnimation.calculationMode = kCAAnimationPaced;
        pathAnimation.fillMode = kCAFillModeBackwards;
        pathAnimation.removedOnCompletion = NO;
        pathAnimation.duration = 5;
        pathAnimation.repeatCount = 1000;

    //create a path for the object or layer to go on
        CGMutablePathRef curvedPath = CGPathCreateMutable();
        CGPathMoveToPoint(curvedPath, NULL, 220, 10);
    CGPathAddArc(curvedPath, NULL, 100, 100, 90, -M_PI_2, M_PI_2, 1);
    CGPathAddArc(curvedPath, NULL, 220, 100, 90, M_PI_2, -M_PI_2, 1);
        //set the path then release
        pathAnimation.path = curvedPath;
        CGPathRelease(curvedPath);

    //set size of the layer and get the context
        UIGraphicsBeginImageContext(CGSizeMake(20,20));
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        //set line width and fill color
        CGContextSetLineWidth(ctx, 1.5);
        CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor);
    //add the rectangle to the context (runner)
    CGContextAddRect(ctx, CGRectMake(1, 1, 15, 15));
    //draw the path
        CGContextDrawPath(ctx, kCGPathFillStroke);
        UIImage *runner = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        UIImageView *runnerView = [[UIImageView alloc] initWithImage:runner];
    //add outline around runner
        runnerView.frame = CGRectMake(1, 1, 20, 20);

        [self addSubview:runnerView];

        [runnerView.layer addAnimation:pathAnimation forKey:@"moveTheSquare"];
}
- (void) animateSecondRunner
{
    //create an animation and give it certain specs
        CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        pathAnimation.calculationMode = kCAAnimationPaced;
        pathAnimation.fillMode = kCAFillModeBackwards;
        pathAnimation.removedOnCompletion = NO;
        pathAnimation.duration = 5;
        pathAnimation.repeatCount = 1000;

    //create a path for the object or layer to go on
        CGMutablePathRef curvedPath = CGPathCreateMutable();
        CGPathMoveToPoint(curvedPath, NULL, 220, 10);
    CGPathAddArc(curvedPath, NULL, 100, 100, 90, -M_PI_2, M_PI_2, 1);
    CGPathAddArc(curvedPath, NULL, 220, 100, 90, M_PI_2, -M_PI_2, 1);
        //set the path then release
        pathAnimation.path = curvedPath;
        CGPathRelease(curvedPath);

    //set size of the layer and get the context
        UIGraphicsBeginImageContext(CGSizeMake(20,20));
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        //set line width and fill color
        CGContextSetLineWidth(ctx, 1.5);
        CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor);
    //add the rectangle to the context (runner)
    CGContextAddRect(ctx, CGRectMake(1, 1, 15, 15));
    //draw the path
        CGContextDrawPath(ctx, kCGPathFillStroke);
        UIImage *runner = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        UIImageView *runnerView = [[UIImageView alloc] initWithImage:runner];
    //add outline around runner
        runnerView.frame = CGRectMake(1, 1, 20, 20);

        [self addSubview:runnerView];

        [runnerView.layer addAnimation:pathAnimation forKey:@"moveTheSquare"];
}
- (void) drawTrack
{

        UIGraphicsBeginImageContext(CGSizeMake(320,460));
        CGContextRef currentContext = UIGraphicsGetCurrentContext();

        CGContextSetLineWidth(currentContext, 6);
        CGContextSetStrokeColorWithColor(currentContext, [UIColor whiteColor].CGColor);


    //choost starting point, then add arc (half circle)
    //the second parameter of CGContextAddArc is the changes how long the line is (horizontal)
    //draw from -PI to PI and the other way around 
        CGContextMoveToPoint(currentContext, 200, 10);
    CGContextAddArc(currentContext, 100, 100, 90, -M_PI_2, M_PI_2, 1);
    CGContextAddArc(currentContext, 220, 100, 90, M_PI_2, -M_PI_2, 1);
    CGContextClosePath(currentContext);

    //draw the path on the context
        CGContextDrawPath(currentContext, kCGPathStroke);

    //create track
        UIImage *track = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

    //add track to view 
        UIImageView *trackView = [[UIImageView alloc] initWithImage:track];
        trackView.frame = CGRectMake(1, 1, 320, 460);
        trackView.backgroundColor = [UIColor clearColor];
        [self addSubview:trackView];


}

@end

1 个答案:

答案 0 :(得分:1)

您应首先参数化一个函数,而不是编写两个几乎相同的函数。然后(至少)你不会让人摸不着头脑,想知道他们是如何不同的。

我将此作为答案而不仅仅是评论,因为在确定要传递哪些参数以及如何使用它们的过程中,您可能会自己发现您做错了什么。