2013-06-08 6 views
6

Ho letto la documentazione su CAShapeLayer ma non riesco ancora a capirlo. Da quanto ho capito, Layer è sempre piatto e le sue dimensioni sono sempre un rettangolo.iOS: CAShapeLayer per disegnare un'immagine non-rectagular e animarne la forma

CAShapeLayer d'altra parte, consente di definire un livello non solo rettangolare. Può essere una forma circolare, un triangolo ecc. A patto che lo si usi con UIBezierPaths.

La mia comprensione è qui?

Quello che avevo in mente è, ad esempio, una palla da tennis che rimbalza sui bordi dello schermo (abbastanza facile), ma mi piacerebbe mostrare una piccola animazione non usando le animazioni di immagini - Mi piacerebbe che mostri un po '"compresso" come l'animazione che colpisce il bordo dello schermo e poi rimbalza. Non sto usando un'immagine della pallina da tennis. Solo un cerchio colorato di colore giallo.

Sono corretto qui con CAShapeLayer per realizzare questo? In tal caso, può fornire un piccolo esempio? Grazie.

+0

Va perfettamente bene – Dabrut

risposta

14

Mentre si utilizza un percorso per definire la forma del livello, viene comunque creato con un rettangolo utilizzato per definire i bordi/i bordi. Ecco un esempio per iniziare:

TennisBall.h:

#import <UIKit/UIKit.h> 

@interface TennisBall : UIView 

- (void)bounce; 

@end 

TennisBall.m:

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

@implementation TennisBall 

+ (Class)layerClass 
{ 
    return [CAShapeLayer class]; 
} 

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

/* Create the tennis ball */ 
- (void)setupLayer 
{ 
    CAShapeLayer *layer = (CAShapeLayer *)self.layer; 
    layer.strokeColor = [[UIColor blackColor] CGColor]; 
    layer.fillColor = [[UIColor yellowColor] CGColor]; 
    layer.lineWidth = 1.5; 

    layer.path = [self defaultPath]; 
} 

/* Animate the tennis ball "bouncing" off of the side of the screen */ 
- (void)bounce 
{ 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"]; 
    animation.duration = 0.2; 
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    animation.fromValue = (__bridge id)[self defaultPath]; 
    animation.toValue = (__bridge id)[self compressedPath]; 
    animation.autoreverses = YES; 
    [self.layer addAnimation:animation forKey:@"animatePath"]; 
} 

/* A path representing the tennis ball in the default state */ 
- (CGPathRef)defaultPath 
{ 
    return [[UIBezierPath bezierPathWithOvalInRect:self.frame] CGPath]; 
} 

/* A path representing the tennis ball is the compressed state (during the bounce) */ 
- (CGPathRef)compressedPath 
{ 
    CGRect newFrame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width * 0.85, self.frame.size.height); 
    return [[UIBezierPath bezierPathWithOvalInRect:newFrame] CGPath]; 
} 

@end 

Ora, quando si desidera utilizzare questo:

TennisBall *ball = [[TennisBall alloc] initWithFrame:CGRectMake(10, 10, 100, 100)]; 
[self.view addSubview:ball]; 

[ball bounce]; 

No te che questo dovrà essere esteso in modo da poter "rimbalzare" da diverse angolazioni, ecc. ma dovrebbe farti puntare nella giusta direzione!

+0

Ehi, felice che tu abbia trovato utile questo. Se risponde alla tua domanda originale, contrassegnala come risposta corretta e fai una nuova domanda sulla UIImmagine poiché è una tecnica completamente diversa! – lnafziger

+1

Crea una seconda palla proprio come hai fatto la prima (creando 'TennisBall * ball2 = ...' e aggiungila come sottoview). – lnafziger