OC實現水波紋動畫
阿新 • • 發佈:2019-01-10
用OC原生的貝塞爾曲線來實現該效果,下面直接上程式碼:
- (void)showWatterRippleAnimation { btnWatter = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 120, 120)]; btnWatter.layer.cornerRadius = 60.f; btnWatter.center = self.view.center; btnWatter.layer.borderColor = [UIColor darkGrayColor].CGColor; btnWatter.layer.borderWidth = 1; btnWatter.backgroundColor = [UIColor lightGrayColor]; [self.view addSubview:btnWatter]; [self addAnimationView]; //如果要實現圖2效果,則開啟此程式碼 // _animationTimer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(addAnimationView) userInfo:nil repeats:YES]; // [_animationTimer fire]; } - (void)addAnimationView { _animationViewsArr = [NSMutableArray array]; //繪製3條貝塞爾曲線儲存起來進行動畫處理 for (int i = 0; i < 3; i++) { CAShapeLayer *layer = [self getShapeLayer]; [_animationViewsArr addObject:layer]; [btnWatter.layer addSublayer:layer]; [self addAnimationWithShapeLayer:layer delay:i*spaceTime]; } } //將目標曲線做放大動畫 - (void)addAnimationWithShapeLayer:(CAShapeLayer*)layer delay:(CGFloat)delayTime { CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; //修改變化大小 scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.5, 1.5, 1)]; //修改變化透明度 CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; alphaAnimation.fromValue = @0.4; alphaAnimation.toValue = @0; //設定動畫 CAAnimationGroup *animation = [CAAnimationGroup animation]; animation.animations = @[scaleAnimation, alphaAnimation]; animation.duration = 3 * spaceTime; animation.repeatCount = CGFLOAT_MAX; //如果要實現圖2效果,設為1 animation.beginTime = delayTime + CACurrentMediaTime(); animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards; [layer addAnimation:animation forKey:nil]; } //以btnWatter為中心繪製貝塞爾曲線 - (CAShapeLayer*)getShapeLayer { CGRect pathFrame = CGRectMake(-CGRectGetMidX(btnWatter.bounds), -CGRectGetMidY(btnWatter.bounds), btnWatter.frame.size.width, btnWatter.frame.size.height); UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:pathFrame cornerRadius:btnWatter.frame.size.width / 2]; CAShapeLayer *pathLayer = [CAShapeLayer layer]; pathLayer.lineWidth = 1; pathLayer.position = CGPointMake(btnWatter.frame.size.width/2, btnWatter.frame.size.height/2); pathLayer.opacity = 0.0f; pathLayer.strokeColor = [UIColor lightGrayColor].CGColor; pathLayer.path = path.CGPath; pathLayer.fillColor = nil; // 預設為blackColor return pathLayer; }
需要注意的是,當動畫在進行的時候如果home再返回前臺,動畫會出現未知的效果。所以需要監聽一下進入後臺和回到前臺的通知,並且實現停止和開始的方法:
- (void)startAnimation { for (int i = 0; i < 3; i++) { CAShapeLayer *layer = self.animationViewsArr[i]; layer.hidden = NO; } } - (void)stopAnimation { for (int i = 0; i < 3; i++) { CAShapeLayer *layer = self.animationViewsArr[i]; layer.hidden = YES; } }