2013-09-02 15 views
9

W mojej aplikacji na iPhone'a potrzebuję wprowadzić inny typ przejścia.Animacja przejść UIView, takich jak expand kropka do okręgu

że był

następny widok otwarty od bieżącego widoku,

to staty jak kropka i kropka rozszerza się powoli jak koło z w kręgu obok widok ma być wyświetlany częściowo w część koła, wreszcie krąg rozszerza się całkowicie, pojawia się kolejny widok.

Przeszukuję wiele przejść, takich jak CATransitions, i niektóre animacje na kontrolerze kakao, ale nie znalazłem tego rodzaju przejścia, czy ktoś może mi pomóc.

enter image description hereenter image description hereenter image description hereenter image description here

Odpowiedz

1

w moim przypadku zrobiłem to w ten sposób:

ustawiony instancji CAShapeLayer jako własność maskować warstwy z widoku niestandardowego podklasa

@interface MyCustomView() 
@property (nonatomic, strong) CircleShapeLayer *circleShapeLayer; 
@end 

@implementation MyCustomView 

- (id) initWithFrame: (CGRect) frame { 
    self = [super initWithFrame: CGRectZero]; 
    if (self) { 
     self.layer.mask = self.shapeLayer; 
     [self.layer.mask setValue: @(0) forKeyPath: @"transform.scale"]; 
    } 
    return self; 
} 

zoom warstwa ta maska ​​do pełnych rozmiarach. Kod z widoku:

- (void) zoom { 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath: @"transform.scale"]; 
    animation.fromValue = [self.layer.mask valueForKeyPath: @"transform.scale"]; 
    animation.toValue = @(1); 
    animation.duration = 2.0; 
    animation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]; 
    animation.delegate = self; 
    // Important: change the actual layer property before installing the animation. 
    [self.layer.mask setValue: animation.toValue forKeyPath: animation.keyPath]; 
    // Now install the explicit animation, overriding the implicit animation. 
    [self.layer.mask addAnimation: animation forKey: animation.keyPath]; 
    return; 
} 

- (CAShapeLayer *) circleShapeLayer { 
    if (!_ circleShapeLayer) { 
     _circleShapeLayer = [SGMaskLayer layer]; 
     _circleShapeLayer.delegate = _shapeLayer; 
     _circleShapeLayer.frame = self.bounds; 
     _circleShapeLayer.needsDisplayOnBoundsChange = YES; 
    } 

    return _circleShapeLayer; 
} 

@end 

kod warstwy maski:

@interface CircleShapeLayer : CAShapeLayer 
@end 

@implementation CircleShapeLayer 

- (void) drawLayer: (CALayer *) layer inContext: (CGContextRef) ctx { 
    UIGraphicsPushContext(ctx); 
    UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect: self.bounds]; 
    self.path = circlePath.CGPath; 
    UIGraphicsPopContext(); 
} 

@end 

z dokumentacją:

kanał alfa warstwy określa, ile z treści warstwy i tła pokazuje przez. Pełne lub częściowe nieprzezroczyste piksele umożliwiają wyświetlanie przez bazowe treści przez całkowicie przezroczyste piksele, ale blokują tę zawartość.

Domyślna wartość tej właściwości to zero. Podczas konfigurowania maski pamiętaj o ustawieniu rozmiaru i położenia warstwy maski na , aby upewnić się, że jest odpowiednio wyrównana z warstwą, którą maskuje.

więc narysowałem okrąg z UIBezierPath, aby uzyskać okrągłą maskę. na początku ustawiam współczynnik skali maski na 0, więc nic z warstwy widoku nie jest widoczne. następnie współczynnik skali jest ustawiony na 1 (wypełniając granice warstwy), co daje przyjemną animację okręgu zwiększającego jego promień od środka.

Możesz potrzebować jeszcze jednej animacji przesuwającej środkowy punkt widoku. obie animacje można zawijać w grupie CAAnimationGroup.

+0

myślę, że może pomóżcie, ale bądźcie pewni, proszę, proszę – user2732294

+0

Mam nadzieję, że moje edycje uczyniły go nieco jaśniejszym. – hacker2007

+0

@ hacker2007 Czy mógłbyś powiedzieć mi więcej szczegółów na temat "myView", "self.shapeLayer" i "self.layer"? –

2

Dobrze myślę, że mogę zaoferować obejścia. Zamiast naciskać do następnego widoku jak kropka. Proponuję dodać prostą animację kropkową w widoku ViewWillAppear widoku, w którym trzeba się popchnąć. Teraz metoda Push pozostałaby taka sama jak

[self.navigationController pushViewController:NewView animated:YES]; 

Ale w ViewWillAppear kod byłby taki, że kropka rozwinie się do kręgu i ujawni nowy View pod nim. Mam nadzieję, że rozumiesz logikę, którą próbuję tutaj wyjaśnić. Każdy problem daj mi znać.

+0

jest jakiś sposób, aby dostać się wokół animacji – user2732294

+0

zrobić bardzo małej kropki krąg i przybliżyć go .... – IronManGill

1

Otwórz w pierwszym widoku:

// Delegat metoda adnotacji została wybrana - (void) tapOnAnnotation: (RMAnnotation *) adnotacja onMap: (RMMapView *) map; { // Aby uzyskać punkt dotykowy znacznika GMS, aby ustawić je jako koło tranzytowe pos CGPoint markerPoint = adnotation.position; x = markerPoint.x; y = markerPoint.y;

circleSize = 10; 
    radiusChange = 0; 

    //Populate Same Values to next view to close 
    VenueScreen.x = x; 
    VenueScreen.y = y; 

    VenueScreen.view.hidden = YES; 
    timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(openVenueScreen) userInfo:nil repeats:YES]; 
    VenueScreen.view.frame = CGRectMake(0, 0, 320, 480); 
    [self.view addSubview:VenueScreen.view]; 

} 



//Circular transition to open Next view 
-(void)openVenueScreen 
{ 
    VenueScreen.view.hidden = NO; 
    VenueScreen.view.userInteractionEnabled = NO; 
    VenueScreen.view.alpha = 0.9; 
    self.view.userInteractionEnabled = NO; 

    int rChange = 0; // Its doing proper masking while changing this value 
    int radius = circleSize-rChange; 

    CAShapeLayer *circleShapeLayer = [CAShapeLayer layer]; 

    // Make a circular shape 
    circleShapeLayer.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(x+radiusChange, y+radiusChange, 2.0*radius, 2.0*radius) 
                 cornerRadius:radius].CGPath; 
    radiusChange = radiusChange-10; 

    // Configure the apperence of the circle 
    [[VenueScreen.view layer] setMask:circleShapeLayer]; 

    //Start Transition 
    circleSize = circleSize+10; 

    if (circleSize > 480) 
    { 
     [[VenueScreen.view layer] setMask:nil]; 

     [timer invalidate]; //Stop titmer 

     VenueScreen.view.userInteractionEnabled = YES; 
     self.view.userInteractionEnabled = YES; 
     VenueScreen.view.alpha = 1; 

     //Populate to next view to close 
     VenueScreen.radiusChange = radiusChange; 
    } 

} 

Close w Dalej Widok:

//Close button Action 
-(IBAction)DismissVenueScreen:(id)sender; 
{ 
    timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(dismissVenueScreen) userInfo:nil repeats:YES]; 
    NSLog(@"close button clciked"); 
} 

//Circular trasition to Close window 
-(void)dismissVenueScreen 
{ 
    int rChange = 0; // Its doing proper masking while changing this value 
    int radius = circleSize-rChange; 

    CAShapeLayer *circleShapeLayer = [CAShapeLayer layer]; 
    // Make a circular shape 
    circleShapeLayer.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(x+radiusChange,y+radiusChange, 2.0*radius, 2.0*radius) 
                 cornerRadius:radius].CGPath; 

    // Configure the apperence of the circle 
    [[self.view layer] setMask:circleShapeLayer]; 
    self.view.layer.masksToBounds = YES; 

    radiusChange = radiusChange+10; 
    circleSize = circleSize-10; 

    if (circleSize <= 0) 
    { 
     [timer invalidate]; //Stop titmer 
     [[self.view layer] setMask:nil]; 
     [self.view removeFromSuperview]; 
     circleSize = 480; 
    } 

}