2014-09-02 5 views
0

Je veux faire un slide-out menu dans mon iPhone application similaire à THIS l'imageQuelle est la meilleure façon d'animer les boutons?

Pour le bouton de menu, je voudrais ajouter une animation à la touche de menu lorsque vous appuyez presque identique à THIS

Mon question est: Quelle est la meilleure façon d'effectuer l'animation?

  1. Est-ce que je crée une image GIF puis briser le GIF jusqu'à ses images individuelles et joue simplement le tableau d'images l'un après l'autre lorsque le bouton est pressé pour reproduire le GIF? Est-ce que je dessine les 3 lignes du bouton de menu comme dans l'exemple de code 1 ci-dessous et quand j'appuie sur le bouton J'anime les lignes comme dans l'exemple de code 2. Je peux dessiner les 3 lignes représentant l'icône de menu sur l'écran puis, lorsque vous appuyez sur le bouton de menu, déplacez les lignes du haut et du bas vers la ligne du milieu. Quand ils atteignent la ligne médiane, retirez l'une des lignes, puis tourner les 2 lignes restantes à +45 et -45 degrés pour donner l'apparence X

code * Les échantillons visible uniquement à titre d'exemple et pas de code réel mis en œuvre

Exemple de code 1.

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, 1)]; 
lineView.backgroundColor = [UIColor blackColor]; 
[self.view addSubview:lineView]; 
[lineView release]; 

Exemple de code 2.

+(void)rotateViewLikeCircle:(UIView*)view rotation:(int)numberOfRotation 
{ 
    CABasicAnimation *rotationAnimation; 
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    rotationAnimation.toValue = [NSNumber numberWithFloat:DEGREES_TO_RADIANS(180)]; 
    rotationAnimation.duration = 0.75; 
    rotationAnimation.repeatCount = numberOfRotation; 
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 

    [view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
} 

Répondre

1

J'ai aimé votre question et a commencé travailler sur la méthode que vous avez décrite et appris beaucoup de choses dans le processus. Je joins mon code. Mais il y a un petit problème, dans la dernière partie de l'extinction de l'animation. C'est un peu secoué, mais ça va ressembler à de l'animation vu que la taille du bouton est petite et la durée de l'animation est très réduite.

Faites-moi savoir, si vous pouvez améliorer mon code sur cette partie saccadée.

@interface YourViewController() 

@property (strong, nonatomic) CALayer *layer1; 
@property (strong, nonatomic) CALayer *layer2; 
@property (strong, nonatomic) CALayer *layer3; 

@property (assign, nonatomic) BOOL isBtnStateOn; 

@end 

@implementation YourViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self createBtnSetup]; 
} 

- (void)createBtnSetup 
{ 
    self.layer1 = [self createLayerWithFrame:CGRectMake(40, 50, 60, 10)]; 
    self.layer2 = [self createLayerWithFrame:CGRectMake(40, 80, 60, 10)]; 
    self.layer3 = [self createLayerWithFrame:CGRectMake(40, 110, 60, 10)]; 

    // Place transparent button on top of layers. 
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 
    [btn setFrame:CGRectMake(40, 50, 60, 70)]; 
    [btn addTarget:self action:@selector(btnTapped:) forControlEvents:UIControlEventTouchUpInside]; 
    [self.view addSubview:btn]; 
} 

- (CALayer *)createLayerWithFrame:(CGRect)frame 
{ 
    CALayer *layer = [CALayer layer]; 
    [layer setFrame:frame]; 
    [layer setBackgroundColor:[UIColor blackColor].CGColor]; 
    [layer setCornerRadius:5.f]; 
    [layer setMasksToBounds:YES]; 
    [self.view.layer addSublayer:layer]; 

    return layer; 
} 

- (void)btnTapped:(id)sender 
{ 
    if (self.isBtnStateOn == NO) { 
     self.isBtnStateOn = YES; 
     [self animateBtnToOnState]; 
    } 
    else { 
     self.isBtnStateOn = NO; 
     [self animateBtnToOffState]; 
    } 
} 

- (void)animateBtnToOnState 
{ 
    CABasicAnimation *translateAnim = [self getTranslationAnimationFrom:@(0) to:@(self.layer2.frame.origin.y - self.layer1.frame.origin.y) timingFunction:kCAMediaTimingFunctionEaseIn duration:0.5f beginTime:0.f fillMode:kCAFillModeForwards]; 
    [self.layer1 addAnimation:translateAnim forKey:@"translateAnimation"]; 

    translateAnim = [self getTranslationAnimationFrom:@(0) to:@(self.layer2.frame.origin.y - self.layer3.frame.origin.y) timingFunction:kCAMediaTimingFunctionEaseIn duration:0.5f beginTime:0.f fillMode:kCAFillModeForwards]; 
    [self.layer3 addAnimation:translateAnim forKey:@"translateAnimation"]; 

    CABasicAnimation *opacity = [self getOpacityAnimationFromValue:@(1.f) toValue:@(0.f) timingFunction:kCAMediaTimingFunctionLinear duration:0.f beginTime:0.4f fillMode:kCAFillModeForwards]; 
    [self.layer2 addAnimation:opacity forKey:@"opacityAnimation"]; 

    CABasicAnimation *rotation = [self getRotationAnimationWithFromAngle:@(0) toAngle:@(M_PI_2 + M_PI_4 + M_PI_4/5) timingFunction:kCAMediaTimingFunctionLinear duration:0.5f beginTime:0.5f fillMode:kCAFillModeForwards]; 
    [self.layer1 addAnimation:rotation forKey:@"rotationAnimation"]; 

    rotation = [self getRotationAnimationWithFromAngle:@(0) toAngle:@(M_PI_4) timingFunction:kCAMediaTimingFunctionLinear duration:0.5f beginTime:0.5f fillMode:kCAFillModeForwards]; 
    [self.layer3 addAnimation:rotation forKey:@"rotationAnimation"]; 

    CABasicAnimation *afterRotation = [self getRotationAnimationWithFromAngle:@(M_PI_2 + M_PI_4 + M_PI_4/5) toAngle:@(M_PI_2 + M_PI_4) timingFunction:kCAMediaTimingFunctionEaseIn duration:0.3f beginTime:1.f fillMode:kCAFillModeForwards]; 
    [self.layer1 addAnimation:afterRotation forKey:@"afterRotationAnimation"]; 
} 

- (void)animateBtnToOffState 
{ 
    CABasicAnimation *rotation = [self getRotationAnimationWithFromAngle:@(M_PI_2 + M_PI_4) toAngle:@(0) timingFunction:kCAMediaTimingFunctionEaseIn duration:0.5f beginTime:0.f fillMode:kCAFillModeForwards]; 
    [self.layer1 addAnimation:rotation forKey:@"rotationAnimation"]; 

    rotation = [self getRotationAnimationWithFromAngle:@(M_PI_4) toAngle:@(0) timingFunction:kCAMediaTimingFunctionEaseIn duration:0.5f beginTime:0.f fillMode:kCAFillModeForwards]; 
    [self.layer3 addAnimation:rotation forKey:@"rotationAnimation"]; 

    CABasicAnimation *opacity = [self getOpacityAnimationFromValue:@(0.f) toValue:@(1.f) timingFunction:kCAMediaTimingFunctionLinear duration:0.f beginTime:0.5f fillMode:kCAFillModeBackwards]; 
    [self.layer2 addAnimation:opacity forKey:@"opacityAnimation"]; 

    CABasicAnimation *translateAnim = [self getTranslationAnimationFrom:@(self.layer2.frame.origin.y - self.layer1.frame.origin.y) to:@(-0.25 * (self.layer2.frame.origin.y - self.layer1.frame.origin.y)) timingFunction:kCAMediaTimingFunctionEaseOut duration:0.5f beginTime:0.5f fillMode:kCAFillModeBackwards]; 
    [self.layer1 addAnimation:translateAnim forKey:@"translateAnimation"]; 

    translateAnim = [self getTranslationAnimationFrom:@(self.layer2.frame.origin.y - self.layer3.frame.origin.y) to:@(-0.25 * (self.layer2.frame.origin.y - self.layer3.frame.origin.y)) timingFunction:kCAMediaTimingFunctionEaseOut duration:0.5f beginTime:0.5f fillMode:kCAFillModeBackwards]; 
    [self.layer3 addAnimation:translateAnim forKey:@"translateAnimation"]; 
} 

- (CABasicAnimation *)getTranslationAnimationFrom:(NSNumber *)fromValue to:(NSNumber *)toValue timingFunction:(NSString *)timingFunction duration:(CGFloat)duration beginTime:(CGFloat)beginTime fillMode:(NSString *)fillMode 
{ 
    CABasicAnimation *translate = [self getBasicAnimationWithKeyPath:@"transform.translation.y" fromValue:fromValue toValue:toValue timingFunction:timingFunction duration:duration beginTime:beginTime fillMode:fillMode]; 
    return translate; 
} 

- (CABasicAnimation *)getRotationAnimationWithFromAngle:(NSNumber *)fromAngle toAngle:(NSNumber *)toAngle timingFunction:(NSString *)timingFunction duration:(CGFloat)duration beginTime:(CGFloat)beginTime fillMode:(NSString *)fillMode 
{ 
    CABasicAnimation *rotation = [self getBasicAnimationWithKeyPath:@"transform.rotation.z" fromValue:fromAngle toValue:toAngle timingFunction:timingFunction duration:duration beginTime:beginTime fillMode:fillMode]; 
    return rotation; 
} 

- (CABasicAnimation *)getOpacityAnimationFromValue:(NSNumber *)fromValue toValue:(NSNumber *)toValue timingFunction:(NSString *)timingFunction duration:(CGFloat)duration beginTime:(CGFloat)beginTime fillMode:(NSString *)fillMode 
{ 
    CABasicAnimation *opacity = [self getBasicAnimationWithKeyPath:@"opacity" fromValue:fromValue toValue:toValue timingFunction:timingFunction duration:duration beginTime:beginTime fillMode:fillMode]; 
    return opacity; 
} 

- (CABasicAnimation *)getBasicAnimationWithKeyPath:(NSString *)keyPath fromValue:(NSNumber *)fromValue toValue:(NSNumber *)toValue timingFunction:(NSString *)timingFunction duration:(CGFloat)duration beginTime:(CGFloat)beginTime fillMode:(NSString *)fillMode 
{ 
    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:keyPath]; 
    [basicAnimation setFromValue:fromValue]; 
    [basicAnimation setToValue:toValue]; 
    [basicAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:timingFunction]]; 
    [basicAnimation setRepeatCount:0.f]; 
    [basicAnimation setDuration:duration]; 
    [basicAnimation setRemovedOnCompletion:NO]; 
    [basicAnimation setCumulative:YES]; 
    [basicAnimation setFillMode:fillMode]; 
    [basicAnimation setBeginTime:(CACurrentMediaTime() + beginTime)]; 
    return basicAnimation; 
} 

@end 
+0

WOW utilisateur1190882! Merci beaucoup pour ça. Je vais essayer cela le plus tôt possible et vous faire savoir comment je m'entends. J'apprécie beaucoup. Je vois aussi que vous êtes allé avec les rectangles de création comme des lignes et ensuite les animer contre la lecture d'images GIF. Dans l'attente de voir comment cela fonctionne. – heyred

+0

Pas de problème. :) Acceptez ma réponse si cela vous aide après l'avoir essayé. :) – user1190882

+0

Géré pour se déplacer à essayer votre code ce soir et cela fonctionne comme un charme. Comme vous dites il y a un très petit jerk à la fin mais rien de trop sérieux. Je verrai si je peux améliorer le code postal ici, mais pour l'instant, j'accepte cela comme réponse. Merci pour votre aide. – heyred

Questions connexes