效果图
首先你得画出这只眼睛,这是眼睛包括5个部分组成:
1 @property (strong, nonatomic) CAShapeLayer *eyeFirstLightLayer; 2 @property (strong, nonatomic) CAShapeLayer *eyeSecondLightLayer; 3 @property (strong, nonatomic) CAShapeLayer *eyeballLayer; 4 @property (strong, nonatomic) CAShapeLayer *topEyesocketLayer; 5 @property (strong, nonatomic) CAShapeLayer *bottomEyesocketLayer;
然后,还是通过 UIBezierPath 和 CAShapeLayer 这样的老套路来画,代码较多:
1 - (CAShapeLayer *)eyeFirstLightLayer { 2 if (!_eyeFirstLightLayer) { 3 _eyeFirstLightLayer = [CAShapeLayer layer]; 4 CGPoint center = CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) / 2); 5 UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center 6 radius:CGRectGetWidth(self.frame) * 0.2 7 startAngle:(230.f / 180.f) * M_PI 8 endAngle:(265.f / 180.f) * M_PI 9 clockwise:YES]; 10 _eyeFirstLightLayer.borderColor = [UIColor blackColor].CGColor; 11 _eyeFirstLightLayer.lineWidth = 5.f; 12 _eyeFirstLightLayer.path = path.CGPath; 13 _eyeFirstLightLayer.fillColor = [UIColor clearColor].CGColor; 14 _eyeFirstLightLayer.strokeColor = [UIColor whiteColor].CGColor; 15 } 16 return _eyeFirstLightLayer; 17 } 18 19 - (CAShapeLayer *)eyeSecondLightLayer { 20 if (!_eyeSecondLightLayer) { 21 _eyeSecondLightLayer = [CAShapeLayer layer]; 22 CGPoint center = CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) / 2); 23 UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center 24 radius:CGRectGetWidth(self.frame) * 0.2 25 startAngle:(211.f / 180.f) * M_PI 26 endAngle:(220.f / 180.f) * M_PI 27 clockwise:YES]; 28 _eyeSecondLightLayer.borderColor = [UIColor blackColor].CGColor; 29 _eyeSecondLightLayer.lineWidth = 5.f; 30 _eyeSecondLightLayer.path = path.CGPath; 31 _eyeSecondLightLayer.fillColor = [UIColor clearColor].CGColor; 32 _eyeSecondLightLayer.strokeColor = [UIColor whiteColor].CGColor; 33 34 } 35 return _eyeSecondLightLayer; 36 } 37 38 - (CAShapeLayer *)eyeballLayer { 39 if (!_eyeballLayer) { 40 _eyeballLayer = [CAShapeLayer layer]; 41 CGPoint center = CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) / 2); 42 UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center 43 radius:CGRectGetWidth(self.frame) * 0.3 44 startAngle:(0.f / 180.f) * M_PI 45 endAngle:(360.f / 180.f) * M_PI 46 clockwise:YES]; 47 _eyeballLayer.borderColor = [UIColor blackColor].CGColor; 48 _eyeballLayer.lineWidth = 1.f; 49 _eyeballLayer.path = path.CGPath; 50 _eyeballLayer.fillColor = [UIColor clearColor].CGColor; 51 _eyeballLayer.strokeColor = [UIColor whiteColor].CGColor; 52 _eyeballLayer.anchorPoint = CGPointMake(0.5, 0.5); 53 54 } 55 return _eyeballLayer; 56 } 57 58 - (CAShapeLayer *)topEyesocketLayer { 59 if (!_topEyesocketLayer) { 60 _topEyesocketLayer = [CAShapeLayer layer]; 61 CGPoint center = CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) / 2); 62 UIBezierPath *path = [UIBezierPath bezierPath]; 63 [path moveToPoint:CGPointMake(0, CGRectGetHeight(self.frame) / 2)]; 64 [path addQuadCurveToPoint:CGPointMake(CGRectGetWidth(self.frame), CGRectGetHeight(self.frame) / 2) 65 controlPoint:CGPointMake(CGRectGetWidth(self.frame) / 2, center.y - center.y - 20)]; 66 _topEyesocketLayer.borderColor = [UIColor blackColor].CGColor; 67 _topEyesocketLayer.lineWidth = 1.f; 68 _topEyesocketLayer.path = path.CGPath; 69 _topEyesocketLayer.fillColor = [UIColor clearColor].CGColor; 70 _topEyesocketLayer.strokeColor = [UIColor whiteColor].CGColor; 71 } 72 return _topEyesocketLayer; 73 } 74 75 - (CAShapeLayer *)bottomEyesocketLayer { 76 if (!_bottomEyesocketLayer) { 77 _bottomEyesocketLayer = [CAShapeLayer layer]; 78 CGPoint center = CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame) / 2); 79 UIBezierPath *path = [UIBezierPath bezierPath]; 80 [path moveToPoint:CGPointMake(0, CGRectGetHeight(self.frame) / 2)]; 81 [path addQuadCurveToPoint:CGPointMake(CGRectGetWidth(self.frame), CGRectGetHeight(self.frame) / 2) 82 controlPoint:CGPointMake(CGRectGetWidth(self.frame) / 2, center.y + center.y + 20)]; 83 _bottomEyesocketLayer.borderColor = [UIColor blackColor].CGColor; 84 _bottomEyesocketLayer.lineWidth = 1.f; 85 _bottomEyesocketLayer.path = path.CGPath; 86 _bottomEyesocketLayer.fillColor = [UIColor clearColor].CGColor; 87 _bottomEyesocketLayer.strokeColor = [UIColor whiteColor].CGColor; 88 89 } 90 return _bottomEyesocketLayer; 91 }
然后更改一下某些属性的值,方便稍后的动画:
1 - (void)setupAnimation { 2 self.eyeFirstLightLayer.lineWidth = 0.f; 3 self.eyeSecondLightLayer.lineWidth = 0.f; 4 self.eyeballLayer.opacity = 0.f; 5 _bottomEyesocketLayer.strokeStart = 0.5f; 6 _bottomEyesocketLayer.strokeEnd = 0.5f; 7 _topEyesocketLayer.strokeStart = 0.5f; 8 _topEyesocketLayer.strokeEnd = 0.5f; 9 }
最后根据 UIScrollView 的 contentOffset
来控制各种属性,办法较笨,但管用。
1 - (void)animationWith:(CGFloat)y { 2 CGFloat flag = self.frame.origin.y * 2.f - 20.f; 3 if (y < flag) { 4 if (self.eyeFirstLightLayer.lineWidth < 5.f) { 5 self.eyeFirstLightLayer.lineWidth += 1.f; 6 self.eyeSecondLightLayer.lineWidth += 1.f; 7 } 8 } 9 10 if(y < flag - 20) { 11 if (self.eyeballLayer.opacity <= 1.0f) { 12 self.eyeballLayer.opacity += 0.1f; 13 } 14 15 } 16 17 if (y < flag - 40) { 18 if (self.topEyesocketLayer.strokeEnd < 1.f && self.topEyesocketLayer.strokeStart > 0.f) { 19 self.topEyesocketLayer.strokeEnd += 0.1f; 20 self.topEyesocketLayer.strokeStart -= 0.1f; 21 self.bottomEyesocketLayer.strokeEnd += 0.1f; 22 self.bottomEyesocketLayer.strokeStart -= 0.1f; 23 } 24 } 25 26 if (y > flag - 40) { 27 if (self.topEyesocketLayer.strokeEnd > 0.5f && self.topEyesocketLayer.strokeStart < 0.5f) { 28 self.topEyesocketLayer.strokeEnd -= 0.1f; 29 self.topEyesocketLayer.strokeStart += 0.1f; 30 self.bottomEyesocketLayer.strokeEnd -= 0.1f; 31 self.bottomEyesocketLayer.strokeStart += 0.1f; 32 } 33 } 34 35 if (y > flag - 20) { 36 if (self.eyeballLayer.opacity >= 0.0f) { 37 self.eyeballLayer.opacity -= 0.1f; 38 } 39 } 40 41 if (y > flag) { 42 if (self.eyeFirstLightLayer.lineWidth > 0.f) { 43 self.eyeFirstLightLayer.lineWidth -= 1.f; 44 self.eyeSecondLightLayer.lineWidth -= 1.f; 45 } 46 } 47 }
最后
总之使用 UIbezierPath 和 CAShapeLayer 可以画出你想要的任何形状,没有它做不到,只有你想不到,搞定了它们你就可以轻松定制你想要的任何控件了。