2013-06-08 26 views
6

Czytałem dokumentację na CAShapeLayer, ale wciąż nie całkiem rozumiem. Z mojego rozumowania Layer jest zawsze płaski, a jego rozmiar jest zawsze prostokątem.iOS: CAShapeLayer do rysowania obrazu nieprostowego i animowania jego kształtu

CAShapeLayer z drugiej strony, pozwala zdefiniować warstwę, która nie jest podobna do prostokąta. Może to być kształt koła, trójkąt itp., O ile używasz go z UIBezierPaths.

Czy moje zrozumienie jest tutaj?

To, co miałem na myśli, to na przykład piłka tenisowa odbijająca się od krawędzi ekranu (dość łatwa), ale chciałabym pokazać małą animację, która nie korzysta z animacji obrazu - chciałbym ją pokazać trochę "ściśnięte" jak animacja, gdy uderza w krawędź ekranu, a potem odskakuje. Nie używam obrazu piłki tenisowej. Tylko okrąg wypełniony żółtym kolorem.

Czy mam tutaj do czynienia z CAShapeLayer, aby to osiągnąć? Jeśli tak, czy możesz podać przykład? Dzięki.

+0

Wszystko jest w porządku – Dabrut

Odpowiedz

14

Podczas gdy używasz ścieżki do zdefiniowania kształtu warstwy, nadal jest ona tworzona za pomocą prostokąta używanego do definiowania ramki/obwiedni. Oto przykład, jak zacząć grę:

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 

Teraz, gdy chcemy korzystać z tego:

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

[ball bounce]; 

Nie że będzie to konieczne, aby można było "podskakiwać" pod różnymi kątami itd., ale powinno to doprowadzić cię do właściwego kierunku!

+0

Hej, cieszę się, że uznałeś to za przydatne. Jeśli odpowiada na twoje oryginalne pytanie, zaznacz je jako poprawną odpowiedź i zadaj nowe pytanie dotyczące UIImage, ponieważ jest to zupełnie inna technika! – lnafziger

+1

Po prostu utwórz drugą kulkę, podobnie jak pierwszą (tworząc "Tennis Ball * ball2 = ..." i dodaj ją jako wyekspozycję). – lnafziger

Powiązane problemy