2013-09-02 15 views
9

Nella mia app per iPhone ho bisogno di implementare un diverso tipo di transizione.animare le transizioni UIView come espandere il punto sul cerchio

che era

prossimo vista dalla vista corrente,

esso previsti come un punto, e il punto espande lentamente come un cerchio con nel cerchio vista successiva deve essere visualizzato parzialmente con la parte del cerchio, infine il cerchio si espande totalmente, la vista successiva appare completamente.

Cerco molte transizioni come CATransitions e alcune animazioni sul controller del cacao, ma non ho trovato questo tipo di transizione, qualcuno può aiutarmi per favore.

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

risposta

1

nel mio caso l'ho fatto in questo modo:

impostare un'istanza CAShapeLayer come proprietà maschera del livello della vostra abitudine vista sottoclasse

@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 questo livello maschera a tutto schermo. Codice della vista:

- (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 

il codice dello strato di maschera:

@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 

dalla documentazione:

canale alfa del livello determina la quantità del contenuto del livello e lo sfondo mostra attraverso. I pixel completamente o parzialmente opachi consentono a di visualizzare il contenuto sottostante ma i pixel completamente trasparenti bloccano tale contenuto.

Il valore predefinito di questa proprietà è pari a zero. Quando si configura una maschera , ricordare di impostare la dimensione e la posizione del livello maschera su assicurandosi che sia allineata correttamente con il livello mascherato.

così ho disegnato un cerchio con UIBezierPath per ottenere la maschera rotonda. all'inizio ho impostato il fattore di scala della maschera su 0, quindi nulla del livello della vista è visibile. quindi il fattore di scala è impostato su 1 (riempiendo i limiti del livello) animato che dà una bella animazione di un cerchio aumentandone il raggio dal centro.

potresti aver bisogno di un'altra animazione spostando il punto centrale della vista. entrambe le animazioni possono essere racchiuse in un CAAnimationGroup.

+0

Penso che possa aiuto, ma sii un po 'di chiarezza per favore – user2732294

+0

Spero che le mie modifiche lo rendano un po' più chiaro – hacker2007

+0

@ hacker2007 Puoi dirmi qualche altro dettaglio su "myView", "self.shapeLayer" e "self.layer"? –

2

Beh credo di poter offrire una soluzione alternativa. Invece di spingere alla vista successiva come un punto. Ti suggerisco di aggiungere una semplice animazione punto nella ViewWillAppear della vista in cui devi essere spinto. Ora il metodo push sarebbe rimasta la stessa come

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

Ma nel ViewWillAppear il codice sarebbe tale che il punto si espanderebbe a un cerchio e rivelare la nuova vista sotto di esso. Spero tu capisca la logica che sto cercando di spiegare qui. Qualsiasi problema fammi sapere.

+0

c'è un modo per ottenere l'animazione intorno – user2732294

+0

Fare un piccolo cerchio di punti e lo zoom in .... – IronManGill

1

Open in prima visione:

// Delegato metodo per l'annotazione stata selezionata - (void) tapOnAnnotation: (RMAnnotation *) annotazione onMap: (RMMapView *) map; { // Per ottenere il punto di tocco del marcatore GMS per impostarli come transito circolare pos CGPoint markerPoint = annotation.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; 
    } 

} 

Chiudi in Prossimo:

//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; 
    } 

} 
Problemi correlati