用径向动画显示UIImage

时间:2012-07-12 18:48:21

标签: ios uiimageview uiimage

我有一个UIImageView,我想以径向顺时针方式慢慢显示。

以下是我想要在1秒钟内显示图像的示例。我基本上试图模拟一个围绕某个东西绘制圆圈的标记。

Radial Image Example

1 个答案:

答案 0 :(得分:4)

这是动画UIBezierPath的另一种变体。最后,提出一个UIBezierPath,然后使用CABasicAnimation的{​​{1}}为其绘制动画:

strokeEnd

你显然必须创建你的bezier。这是我复杂的小算法(它是一个五点的数组,每个点的角度,以及每个点的锚点的权重),但我相信你可以想出更简单的东西:

- (void)drawBezier
{
    CGPoint startPoint = CGPointMake(self.view.frame.size.width / 2.0, 50);

    UIBezierPath *path = [self strokePath:startPoint];

    CAShapeLayer *oval = [[CAShapeLayer alloc] init];
    oval.path = path.CGPath;
    oval.strokeColor = [UIColor redColor].CGColor;
    oval.fillColor = [UIColor clearColor].CGColor;
    oval.lineWidth = 5.0;
    oval.strokeStart = 0.0;
    oval.strokeEnd = 1.0;
    [self.view.layer addSublayer:oval];

    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    anim.duration = 1.0;
    anim.fromValue = [NSNumber numberWithFloat:0.0f];
    anim.toValue = [NSNumber numberWithFloat:1.0f];
    [oval addAnimation:anim forKey:@"strokeEndAnimation"];
}

如果这是不可接受的(因为它是一个坚实的路径,而不是你的艺术渲染),这是一个有效的技巧(但有点复杂,所以忍受我)。您可以将图像放在图层上,将UIBezierPath椭圆放在其上,而不是将贝塞尔曲线路径的图形设置为红色动画,将其绘制为白色,这样它会遮挡您的图像并融入背景,然后反转动画。 UIBezierPath的绘制。这样,它从你的图像开始,在它上面绘制了一个白色的UIBezierPath,完全遮蔽了你的图像,并且它动画了UIBezierPath的未绘制,在下面显示你的图像。但无论如何,这就是你如何将图像添加到图层以及如何“展开”bezier。

- (UIBezierPath *)strokePath:(CGPoint)startPoint
{
    NSArray *points = [NSArray arrayWithObjects:
                       [NSValue valueWithCGPoint:CGPointMake(startPoint.x, startPoint.y)], 
                       [NSValue valueWithCGPoint:CGPointMake(startPoint.x + 100.0, startPoint.y + 70.0)], 
                       [NSValue valueWithCGPoint:CGPointMake(startPoint.x, startPoint.y + 140.0)], 
                       [NSValue valueWithCGPoint:CGPointMake(startPoint.x - 100.0, startPoint.y + 70.0)], 
                       [NSValue valueWithCGPoint:CGPointMake(startPoint.x + 10.0, startPoint.y + 10)], 
                       nil];
    NSArray *angles = [NSArray arrayWithObjects:
                       [NSNumber numberWithFloat:M_PI_2 * 0.05],
                       [NSNumber numberWithFloat:M_PI_2],
                       [NSNumber numberWithFloat:M_PI],
                       [NSNumber numberWithFloat:M_PI_2 * 3],
                       [NSNumber numberWithFloat:0],
                       nil];
    NSArray *weight = [NSArray arrayWithObjects:
                       [NSNumber numberWithFloat:100.0 / 1.7],
                       [NSNumber numberWithFloat: 70.0 / 1.7],
                       [NSNumber numberWithFloat:100.0 / 1.7],
                       [NSNumber numberWithFloat: 70.0 / 1.7],
                       [NSNumber numberWithFloat:100.0 / 1.7],
                       nil];

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:startPoint];

    for (NSInteger i = 1; i < 5; i++)
    {
        CGPoint pointPrevious  = [[points objectAtIndex:(i-1)] CGPointValue];
        CGPoint pointCurrent   = [[points objectAtIndex:i] CGPointValue];

        CGFloat anglePrevious  = [[angles objectAtIndex:(i-1)] floatValue];
        CGFloat angleCurrent   = [[angles objectAtIndex:i] floatValue];

        CGFloat weightPrevious = [[weight objectAtIndex:(i-1)] floatValue];
        CGFloat weightCurrent  = [[weight objectAtIndex:i] floatValue];

        [path addCurveToPoint:pointCurrent
                controlPoint1:CGPointMake(pointPrevious.x + cosf(anglePrevious) * weightPrevious, 
                                          pointPrevious.y + sinf(anglePrevious) * weightPrevious) 
                controlPoint2:CGPointMake(pointCurrent.x  - cosf(angleCurrent)  * weightCurrent,  
                                          pointCurrent.y  - sinf(angleCurrent)  * weightCurrent)];
    }

    return path;
}
显然,必须付出一些努力才能提出直接覆盖你的图像等的UIBezierPath,但它可以做到。 (顺便说一句,如果你(a)绘制UIBezier,(b)拍摄屏幕快照,(c)将其扔进photoshop以借给你想要的外观,然后(d)使用,那么这种练习将大大简化对于潜在的图像。)无论如何,对于我下面的粗略尝试,我只是让bezier的厚度非常厚,所以我可能会非常邋,,但你会想要更加小心(因为我认为你是在你的东西周围绘制你的圆圈,你不能让UIBezierPath叠加模糊不清。

或者,如果你想使用CodaFi的第一个建议,但是还没有创建单独的图像,你可以坚持使用这个超厚的bezier路径,但你可以使用上面代码的排列来创建你的图像(例如,从零开始 CAShapeLayer *imagelayer = [[CAShapeLayer alloc] init]; UIImage *image = [UIImage imageNamed:@"oval.png"]; imagelayer.contents = (id)image.CGImage; imagelayer.frame = CGRectMake(startPoint.x - image.size.width / 2.0, startPoint.y, image.size.width, image.size.height); [self.view.layer addSublayer:imagelayer]; CAShapeLayer *oval = [[CAShapeLayer alloc] init]; oval.path = path.CGPath; oval.strokeColor = [UIColor whiteColor].CGColor; oval.fillColor = [UIColor clearColor].CGColor; oval.lineWidth = 80.0; oval.strokeStart = 0.0; oval.strokeEnd = 0.0; [self.view.layer addSublayer:oval]; CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; anim.duration = 1.0; anim.fromValue = [NSNumber numberWithFloat:1.0f]; anim.toValue = [NSNumber numberWithFloat:0.0f]; [oval addAnimation:anim forKey:@"strokeEndAnimation"]; ,不要同时制作动画,而是拍摄屏幕快照,一次又一次地执行,每次将strokeStart增加1/30(或其他),拍摄另一个屏幕快照等。)。

希望有人能提出更优雅的解决方案!