2012-06-19 36 views
5

Próbuję animować szerokość zaokrąglonego prostokąta, problem polega na tym, że podczas przechodzenia z większej szerokości do mniejszej szerokości animacja wykonuje "skok z aberracją".(iOS) Jak animować zaokrąglony prostokąt z shapeLayer?

Oto kod:

shapeLayer = [CAShapeLayer layer]; 
shapeRect = CGRectMake(0.0f, 0.0f, 150.0f, 200.0f); 
[shapeLayer setBounds:shapeRect]; 
[shapeLayer setPosition:CGPointMake(iniPosX, 80.0f)]; 
[shapeLayer setFillColor:[[UIColor blackColor] CGColor]]; 
[shapeLayer setStrokeColor:[[UIColor clearColor] CGColor]]; 
[shapeLayer setLineWidth:1.0f]; 
[shapeLayer setLineJoin:kCALineJoinRound]; 
[shapeLayer setOpacity:0.2]; 
path = [UIBezierPath bezierPathWithRoundedRect:shapeRect cornerRadius:15.0]; 
[shapeLayer setPath:path.CGPath]; 
[self.layer addSublayer:shapeLayer]; 

I kiedy rozpocząć animację:

- (void)adjustSelectorToPosAndSize:(float)posX andWidth:(float)width 
{ 
    shapeRect = CGRectMake(0.0f, 0.0f, width, 200.0f); 
    [shapeLayer setBounds:shapeRect]; 
    [shapeLayer setPosition:CGPointMake(posX, 80.0f)]; 
    path = [UIBezierPath bezierPathWithRoundedRect:shapeRect cornerRadius:15.0]; 
    [shapeLayer setPath:path.CGPath]; 
} 

Co robię źle?

+0

Dzięki za korektę Alexis. – murb83

Odpowiedz

3

Wykonanie tego przy użyciu metody CAShapeLayer wydaje się zbyt skomplikowane, jeśli używasz go tylko do zaokrąglonego prostokąta. Dlaczego po prostu nie użyć zestawu CALayer z zestawem the cornerRadius properly?

Animowanie ramki za pomocą zestawu rogu Radius będzie działać poprawnie.

myLayer = [CALayer layer]; 
shapeRect = CGRectMake(0.0f, 0.0f, 150.0f, 200.0f); 
[myLayer setBounds:shapeRect]; 
[myLayer setPosition:CGPointMake(iniPosX, 80.0f)]; 
[myLayer setBackgroundColor:[[UIColor blackColor] CGColor]]; 
[myLayer setBorderColor:[[UIColor clearColor] CGColor]]; 
[myLayer setBorderWidth:1.0f]; 
[myLayer setOpacity:0.2]; 
[myLayer setCornerRadius:15.0]; 
[self.layer addSublayer:myLayer]; 

animowanie to się robi po prostu łańcuchowym ramkę (nie ścieżka)

- (void)adjustSelectorToPosAndSize:(float)posX andWidth:(float)width 
{ 
    shapeRect = CGRectMake(0.0f, 0.0f, width, 200.0f); 
    [myLayer setBounds:shapeRect]; 
    [myLayer setPosition:CGPointMake(posX, 80.0f)]; 
} 

Ważne:

Niektóre właściwości zmienił nazwę jak fillColor stał backgroundColor i strokeColor i lineWidth stała się borderColor i borderWidth itp.

+0

Dzięki! Ale nie robi animacji, jest natychmiastowa. – murb83

+0

Po prostu próbowałem. Animuje się za pomocą domyślnej animacji czasu trwania 0.3. Czy robisz cokolwiek innego z warstwą? –

+0

Jeśli chcesz dostosować animację, musisz to zrobić jawnie. –

3

Chociaż własność ścieżka CAShapeLayer jest animatable, nie robi tego w sposób dorozumiany jak granice i pozycji, trzeba dokonać wyraźnego animację:

CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath: @"path"]; 
anim.fromValue = (id) fromPath.CGPath; 
anim.toValue = (id) toPath.CGPath; 
anim.duration = 1.0; 
[layer addAnimation: anim forKey: @“resize”]; 

Ponieważ prawdopodobnie chcesz wszystkie trzy animacje zdarzyć się razem, można uczynić je wszystkie jawne i grupowane:

CABasicAnimation* anim1 = [CABasicAnimation animationWithKeyPath: @"position"]; 
anim1.fromValue = [NSValue valueWithCGPoint: fromPosition]; 
anim1.toValue = [NSValue valueWithCGPoint: toPosition]; 
anim1.duration = 1.0; 

CABasicAnimation* anim2 = [CABasicAnimation animationWithKeyPath: @"bounds"]; 
anim2.fromValue = [NSValue valueWithCGRect: fromBounds]; 
anim2.toValue = [NSValue valueWithCGRect: toBounds]; 
anim2.duration = 1.0; 

CABasicAnimation* anim3 = [CABasicAnimation animationWithKeyPath: @"path"]; 
anim3.fromValue = (id) fromPath.CGPath; 
anim3.toValue = (id) toPath.CGPath; 
anim3.duration = 1.0; 

CAAnimationGroup* animG = [CAAnimationGroup animation]; 
animG.animations = [NSArray arrayWithObjects: anim1, anim2, anim3, nil]; 
animG.duration = 1.0; 
[layer addAnimation: animG forKey:@"resize"]; 

Jeżeli kształt nie posiada zawartość lub dzieci to może być w stanie używać CALayer zamiast:

CALayer* rectLayer = [CALayer layer]; 
rectLayer.masksToBounds = YES; 
rectLayer.bounds = startBounds; 
rectLayer.backgroundColor = [[UIColor blackColor] CGColor]; 
rectLayer.cornerRadius = 15.0; 
[self.layer addSublayer: rectLayer]; 

// Then later implicitly animate the bounds: 
rectLayer.bounds = newBounds; 
+0

Dzięki! Testuję twój kod, mówię ci, kiedy skończysz testowanie. – murb83

+0

Przykro mi, ale nie działa dobrze, myślę, że robię coś nie tak, ale warstwa nie porusza się tam, gdzie chcę, myślę, że punkt odniesienia jest inny, gdy robię animację. Przepraszam, mój angielski nie jest dobry. Sposób, w jaki korzystasz z animacji, jest naprawdę w moim interesie, otworzyłeś dla mnie nową drogę dla mnie w animacjach grupowych. ^^ – murb83

Powiązane problemy