2014-09-02 4 views
0

Я хочу сделать выдвижное меню в моем iPhone приложении, похожее на THIS изображениеКаков наилучший способ анимировать кнопки?

Для кнопки меню, я хотел бы добавить анимацию в меню кнопки при нажатии почти идентичен THIS

Моих вопрос: Каков наилучший способ выполнения анимации?

  1. ли я создать GIF-изображение, а затем разбить GIF до его отдельных изображений, а затем просто играть массив изображений один за другим, когда кнопка нажата, чтобы повторить GIF?
  2. Я рисую 3 строки кнопки меню, как в примере кода 1. ниже, и когда нажата кнопка, я анимация строк, как в примере кода 2. Я могу нарисовать 3 строки, представляющие значок меню на экране а затем, когда нажата кнопка меню, переместите верхнюю и нижнюю линии к средней линии. Когда они достигают средней линии, удалите одну из линий, а затем закрутить 2 оставшиеся линии до +45 и -45 градусов, чтобы дать рент- внешний вид

* Примеры кода показаны только в качестве примеров, а не фактический реализован код

Пример кода 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]; 

Пример кода 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"]; 
} 

ответ

1

мне понравился ваш вопрос и начал работая над методом, который вы описали, и многому научились в этом процессе. Я прилагаю свой код. Но есть небольшая проблема, в последней части отключения анимации. Он слегка дергается, но он будет выглядеть как часть анимации, учитывая, что размер кнопки мал, а продолжительность анимации очень меньше.

Дайте мне знать, если вы можете улучшить мой код на этой подергивающей части.

@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 пользователь1190882! Спасибо за это целую кучу. Я попробую это как можно скорее и дам вам знать, как я нахожусь. Действительно ценю это. Я также вижу, что вы пошли с создаваемыми прямоугольниками в виде строк, а затем оживили их против воспроизведения изображений GIF. С нетерпением ждем, как эта работа. – heyred

+0

Нет проблем. :) Примите мой ответ, если он поможет вам после того, как вы попробуете его. :) – user1190882

+0

Удалось обойти свой код сегодня вечером, и это работает как шарм. Как вы говорите, в конце есть очень маленький рывок, но ничего серьезного. Я увижу, могу ли я улучшить этот и отправку кода здесь, но на данный момент я принимаю это как ответ. Спасибо за большую помощь. – heyred

Смежные вопросы