我想在我的iPhone应用中制作一个类似于THIS图像
的滑出式菜单对于菜单按钮,我想在按下与THIS几乎相同的菜单按钮时添加动画
我的问题是:执行动画的最佳方式是什么?
*代码示例仅作为示例显示,而不是实际实现的代码
代码示例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"];
}
答案 0 :(得分: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