放射状の時計回りにゆっくりと明らかにしたい UIImageView があります。
これは、1秒間に画像を表示する方法の例です。基本的に、何かの周りに円を描くマーカーをシミュレートしようとしています。
放射状の時計回りにゆっくりと明らかにしたい UIImageView があります。
これは、1秒間に画像を表示する方法の例です。基本的に、何かの周りに円を描くマーカーをシミュレートしようとしています。
a のアニメーション化の別のバリエーションを次に示しUIBezierPath
ます。要するに、UIBezierPath を考え出し、その描画を次の でアニメーション化するだけCABasicAnimation
ですstrokeEnd
。
- (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"];
}
明らかに、ベジエを作成する必要があります。これは私の複雑で小さなアルゴリズムです (これは 5 つのポイント、各ポイントの角度、および各ポイントのアンカー ポイントの重みの配列です) が、もっと簡単なものを思い付くことができると確信しています:
- (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 の楕円をその上に配置し、ベジエ パスの描画を赤でアニメーション化するのではなく、白で描画して画像を覆い隠し、背景に溶け込ませ、アニメーションを逆にすることができますUIBezierPath の描画。そうすれば、画像の上に白い UIBezierPath が描画され、画像が完全に覆い隠され、UIBezierPath の描画解除がアニメーション化され、下の画像が表示されます。とにかく、これはレイヤーに画像を追加する方法と、ベジエを「描画解除」する方法です。
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"];
明らかに、画像などを直接覆う UIBezierPath を考え出すにはいくらかの努力が必要ですが、それは可能です。(ちなみに、この演習は、(a) UIBezier を描画し、(b) 画面のスナップショットを取り、(c) それを Photoshop に投入して、必要な外観に仕上げ、(d)とにかく、下の私の大雑把な試みでは、ベジエの厚さを信じられないほど厚くしたので、かなりずさんになる可能性がありますが、もっと注意する必要があります(私はあなたが何かの周りに円を描くと、UIBezierPath オーバーレイがそれを覆い隠すことはできません)。
または、CodaFi の最初の提案を使用したいが、個々の画像をまだ作成していない場合は、この超太いベジエ パスを使用できますが、上記のコードの順列を使用して画像を作成できます (例: startゼロのstrokeStart
場合、アニメーション化するのではなく、画面のスナップショットを撮り、何度も繰り返して、strokeStart
毎回 1/30 (または何でも) ずつ増やして、別の画面のスナップショットを撮るなど)。
うまくいけば、誰かがよりエレガントなソリューションを考え出すことができます!