2012-04-26 8 views
5

Z pewnych powodów staram się unikać używania opcji CAScrollLayer, aby to zrobić. Efektem, który zamierzam osiągnąć, jest stopniowe ujawnianie (od dołu do góry) treści CALayera (wcześniej załadowanego png). Więc pomyślałem o zrobieniu tego:jak mogę animować granice CAlayer'a, aby stopniowo ujawniać obraz?

layer.anchorPoint = CGPointMake(.5, 1); 
    CABasicAnimation* a = [CABasicAnimation animationWithKeyPath:@"bounds.size.height"]; 
    a.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    a.fillMode = kCAFillModeBoth; 
    a.removedOnCompletion = NO; 
    a.duration = 1; 
    a.fromValue = [NSNumber numberWithFloat:0.]; 
    a.toValue = [NSNumber numberWithFloat:layer.bounds.size.height]; 
    [layer addAnimation:a forKey:nil]; 

Problem z tym jest, można powiedzieć, zawartość warstwy jest skalowana z granicami. Próbowałem zmienić granice, ale zawartość pozostała zawsze oryginalną wielkością, tak aby skutecznie obcinały obraz, a gdy zwiększam granice.wzrost, obraz "Ujawnia się" sam.

Jakieś pomysły, jak je usunąć lub co może mi zabraknąć?

Odpowiedz

3

Ok mam go do pracy, ale w zasadzie musiał aktualizować ramkę warstwy jest też, aby odzwierciedlić zmiany w punkcie kontrolnym:

[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; 
    layer.contentsGravity = kCAGravityTop; 
    layer.masksToBounds = YES; 
    layer.anchorPoint = CGPointMake(.5, 1); 
    CGRect newFrame = layer.frame; 
    newFrame.origin.y += newFrame.size.height/2; 
    layer.frame = newFrame; 
    [CATransaction setValue:(id)kCFBooleanFalse forKey:kCATransactionDisableActions]; 

    a.toValue = [NSNumber numberWithFloat:layer.bounds.size.height]; 
    [layer addAnimation:a forKey:nil]; 
0

Można umieścić inny obraz nad obrazem docelowym i przesunąć go w górę, jak kurtynę sceniczną.

+0

wiem, ale ze względu na skuteczność w więcej niż jednym poziomie (nie może sprowadzić kilka z tych efektów naraz i muszę sam sobie poradzić z CALayers) Postanowiłem nie iść tą drogą. Teraz eksperymentuję z contentRect i udało mi się zrobić to prawie dobrze. Jedynym problemem jest to, że gdy treść jest animowana, dostaję coś w stylu ścieżki rysowanej wewnątrz warstwy. – SaldaVonSchwartz

+0

Dokumentacja dla contentRect mówi, że "jeśli piksele znajdujące się poza prostokąciami jednostki są wymagane, piksele krawędzi obrazu zawartości zostaną rozciągnięte na zewnątrz" Tak więc sądzę, że właśnie dlatego uzyskuję efekt obrysu – SaldaVonSchwartz

2

Co się stanie, jeśli zamiast tego zmienisz maskę przycinającą? (lub użyj warstwy maski).

3

„Tato” ma właściwą odpowiedź.

Chcesz utworzyć warstwę CAShapeLayer i zainstalować ją jako maskę na swojej warstwie.

Tworzysz ścieżkę CGPath, która jest tylko prostokątem i instalujesz tę ścieżkę w warstwie kształtu. Zawartość ścieżki określa, które obszary zamaskowanej warstwy pojawiają się. Jeśli ścieżka jest trójkątem pośrodku warstwy, pojawia się tylko trójkąt.

Następnie należy utworzyć animację animującą ścieżkę.

Aby odsłonić obraz od dołu, należy ustawić ścieżkę, która był prostokątem o wysokości 0 na dole warstwy, a następnie utworzyć CAAnimation, w której toValue jest tym samym prostokątem o wysokości pełnej warstwy, którą chcesz ujawnić. System wygeneruje animację, która odsłania obraz w przeciągu.

Można użyć tej samej techniki, aby osiągnąć wszystkie rodzaje fajne efekty, takie jak drzwi, stodoła, żaluzji, „Iris”, chusteczki itp

+0

Dziękuję za szczegółowy opis –