iOS绘图CALayer、UIBezierPath运用(边框、填充、复制、渐变)
来源:互联网 发布:sql select语句 包含 编辑:程序博客网 时间:2024/06/05 15:27
一.动态折线图效果图
1.首先绘制网格和坐标CAReplicatorLayer
//添加网格图层
//网格列线
CAReplicatorLayer*rowReplicatorLayer = [CAReplicatorLayernew];
_xReplicatorLayer= rowReplicatorLayer;
rowReplicatorLayer.position=CGPointMake(0,0);
CALayer*rowBackLine = [CALayernew];
_xBackLine= rowBackLine;
[rowReplicatorLayeraddSublayer:rowBackLine];
[mainView.layeraddSublayer:rowReplicatorLayer];
//网格横线
CAReplicatorLayer*columnReplicatorLayer = [CAReplicatorLayernew];
_yReplicatorLayer= columnReplicatorLayer;
columnReplicatorLayer.position=CGPointMake(0,0);
CALayer*columnBackLine = [CALayernew];
_yBackLine= columnBackLine;
[columnReplicatorLayeraddSublayer:columnBackLine];
[mainView.layeraddSublayer:columnReplicatorLayer];
//图层绘制动画
[CATransactionbegin];
[CATransactionsetAnimationDuration:0];
CGFloatrowSpacing =_heightGrid;
CGFloatcolumnSpacing =_widthGrid;
//坐标轴这里我简单的使用label循环创建
_XLabelView.frame=CGRectMake(_YLabelWidth-_widthGrid/2,_mainView.frame.size.height-_XLabelHeight,_mainView.frame.size.width-_YLabelWidth,_XLabelHeight);
_YLabelView.frame=CGRectMake(0,0-_heightGrid/2+_YunitLabelHeight,_YLabelWidth,_mainView.frame.size.height-_XLabelHeight);
//图层复制(设置复制的数量)
_xReplicatorLayer.instanceCount=_numberY+1;
_yReplicatorLayer.instanceCount=_valueData.count;
_xReplicatorLayer.instanceTransform=CATransform3DMakeTranslation(0, rowSpacing + _widthLine,0);
_yReplicatorLayer.instanceTransform=CATransform3DMakeTranslation(columnSpacing +_widthLine,0,0);
//设置图层大小
_yReplicatorLayer.frame=_xReplicatorLayer.frame=CGRectMake(_YLabelWidth,_YunitLabelHeight,_mainView.frame.size.width-_YLabelWidth-_spaceWidth,_mainView.frame.size.height-_XLabelHeight-_YunitLabelHeight);
_yBackLine.frame=CGRectMake(0,0,_widthLine,_yReplicatorLayer.frame.size.height);
_xBackLine.frame=CGRectMake(0,0,_yReplicatorLayer.frame.size.width,_widthLine);
[CATransactioncommit];
2.绘制曲线和折点
//曲线
_curveLineLayer.strokeColor=_curveLineColor.CGColor;
_curveLineLayer.lineWidth=_curveLineWidth;
CAShapeLayer*curveLineLayer = [CAShapeLayernew];
_curveLineLayer= curveLineLayer;
curveLineLayer.fillColor=nil;
curveLineLayer.lineJoin=kCALineJoinRound;
[mainView.layeraddSublayer:curveLineLayer];
/**
将数值转换成坐标
*/
-(CGPoint)_changeValueToPoint:(NSDictionary*)data{
CGFloatxValue = [data[JHChartViewX]floatValue];
CGFloatyValue = [data[JHChartViewY]floatValue];
//x坐标等于value*宽度
//y坐标等于value/最大值*y高度
CGPointpoint =CGPointMake(_YLabelWidth+ xValue *(_widthGrid+_widthLine),_YunitLabelHeight+(1-yValue/_maxY)*_yBackLine.frame.size.height);
returnpoint;
}
/**
生成坐标点
*/
-(void)_creatPoint{
_pointData= @[].mutableCopy;
for(NSDictionary*dictin _valueData) {
//转换成当前坐标点
CGPointpoint = [self_changeValueToPoint:dict];
[_pointDataaddObject:[NSValuevalueWithCGPoint:point]];
}
CGFloatsum = 0;
//计算总长度
for(inti =0; i<_pointData.count-1; i++) {
CGPointp1 = [_pointData[i]CGPointValue];
CGPointp2 = [_pointData[i+1]CGPointValue];
CGFloattemp =sqrt(pow((p1.x-p2.x),2)+pow((p1.y-p2.y),2));
sum += temp;
}
_sumLineWidth= sum;
}
/**
生成路径
*/
-(void)_creatPath{
[self_creatPoint];
UIBezierPath* path = [UIBezierPathbezierPath];
UIBezierPath*backPath = [UIBezierPathbezierPath];
CGPointfirstPoint = [_pointData[0]CGPointValue];
CGPointlastPoint = [_pointData[_pointData.count-1]CGPointValue];
[pathmoveToPoint:firstPoint];
[backPathmoveToPoint:CGPointMake(firstPoint.x,_yBackLine.frame.size.height+_YunitLabelHeight)];
for(NSValue*pointValuein_pointData) {
CGPointpoint = [pointValueCGPointValue];
if(pointValue ==_pointData[0]) {
[backPathaddLineToPoint:point];
continue;
}
[backPathaddLineToPoint:point];
[pathaddLineToPoint:point];
}
[backPathaddLineToPoint:CGPointMake(lastPoint.x,_yBackLine.frame.size.height+_YunitLabelHeight)];
_path= path;
//背景路径
_backPath= backPath;
}
/**
绘制坐标点
@param point坐标点
@param index标记tag
*/
- (void)drawPoint:(CGPoint)point withIndex:(NSInteger)index{
}
3.绘制背景
//封闭阴影
CAShapeLayer* backLayer = [CAShapeLayernew];
_backLayer= backLayer;
[mainView.layeraddSublayer:backLayer];
CAShapeLayer*progressLayer = [CAShapeLayerlayer];
_progressLayer= progressLayer;
[_backLayersetMask:progressLayer];
//背景
_backLayer.fillColor=_fillLayerBackgroundColor.CGColor;
_backLayer.hidden=_fillLayerHidden;
//背景路劲
_backLayer.path=_backPath.CGPath;
//背景移动遮罩
CGFloatlineWidth =_yReplicatorLayer.frame.size.height+_YunitLabelHeight;
_progressLayer.lineWidth= lineWidth*2;
_progressLayer.lineCap=kCALineCapSquare;
_progressLayer.strokeColor= [UIColorwhiteColor].CGColor;
//将路径填充颜色设置为透明
_progressLayer.fillColor= [UIColorredColor].CGColor;
4.添加动画效果
4.1曲线绘制动画
CABasicAnimation*pointAnim = [CABasicAnimationanimationWithKeyPath:@"strokeEnd"];
pointAnim.fromValue=@0.0;
pointAnim.toValue=@1.0;
pointAnim.duration=_drawAnimationDuration;
[_curveLineLayeraddAnimation:pointAnimforKey:@"drawLine”];
#warning 背景是默认全部填充的,无法像曲线一样移动,故采用setMask:方法,给它加上一个遮罩。利用遮罩的绘制动画,模拟出背景的动画
//图层直线的轨迹
UIBezierPath*path = [UIBezierPathbezierPath];
#warning起始点似乎有问题
[pathmoveToPoint:CGPointMake(-_widthGrid*2,0)];
[pathaddLineToPoint:CGPointMake(_yReplicatorLayer.frame.size.width,0)];
_progressLayer.path= path.CGPath;
_progressLayer.strokeEnd=0.0;
//动画时间
CGFloatduration =_drawAnimationDuration*(_sumLineWidth/_yReplicatorLayer.frame.size.width);
//进度程度
CGFloatprogress =1.0;
//strokeEnd动画到某个点结束
CABasicAnimation*animate = [CABasicAnimationanimationWithKeyPath:@"strokeEnd"];
animate.removedOnCompletion=NO;
animate.fillMode=kCAFillModeForwards;
animate.duration= duration;
animate.fromValue=@0.0;
animate.toValue=@(progress);
//为图层添加动画
[_progressLayeraddAnimation:animateforKey:@"drawProgress”];
二.动态渐变色百分比移动图效果图
效果图
1.绘制渐变色曲线CAGradientLayer
//将渐变图层添加到animationView的图层上
[self.animationView.layeraddSublayer:self.gradientLayer];
[self.gradientLayeraddSublayer:self.gradientColorLayer];
_gradientLayer= [CALayerlayer];
_gradientColorLayer= [CAGradientLayerlayer];
_gradientLayer.frame=CGRectMake(0,0,_animationView.frame.size.width,_animationView.frame.size.height);
_gradientColorLayer.frame=CGRectMake(0,0,_animationView.frame.size.width,_animationView.frame.size.height);
_gradientColorLayer.cornerRadius=_gradientLayer.frame.size.height/2;
[_gradientColorLayersetColors:[NSArrayarrayWithObjects:(id)_startColor.CGColor,(id)_endColor.CGColor,nil]];
//渐变方向水平
[_gradientColorLayersetStartPoint:CGPointMake(0,1)];
2.添加蒙版CAShapeLayer
CGFloatlineWidth =progressHeight;
_progressLayer= [CAShapeLayerlayer];
_progressLayer.lineWidth= lineWidth*2;
_progressLayer.lineCap=kCALineCapSquare;
_progressLayer.strokeColor= [UIColorwhiteColor].CGColor;
//将路径填充颜色设置为透明
_progressLayer.fillColor= [UIColorclearColor].CGColor;
//用progressLayer来截取渐变层
[self.gradientLayersetMask:self.progressLayer];
3.绘制百分比向下箭头Label
/**
绘制向下的三角形(这里的路径超出了Label,当然我们只要不截取超出部分就行了,不用管原始Label中的文字是否居中)
*/
-(void)drawTriangle{
//圆角矩形
UIBezierPath*path = [UIBezierPathbezierPathWithRoundedRect:_labPercent.framecornerRadius:3];
//三角形
UIBezierPath*trianglePath = [[UIBezierPathalloc]init];
[trianglePathmoveToPoint:CGPointMake(_percentView.frame.size.width/2-2,_percentView.frame.size.height-5)];;
[trianglePathaddLineToPoint:CGPointMake(_percentView.frame.size.width/2,_percentView.frame.size.height)];
[trianglePathaddLineToPoint:CGPointMake(_percentView.frame.size.width/2+2,_percentView.frame.size.height-5)];
//扩展绘制路径
[pathappendPath:trianglePath];
CAShapeLayer*fillLayer = [CAShapeLayerlayer];
fillLayer.path= path.CGPath;
fillLayer.fillColor=kBaseColor.CGColor;
#warning必须将他添加到最下一层,否则会遮挡其他图层
// [_labPercent.layer addSublayer:fillLayer];
[_labPercent.layerinsertSublayer:fillLayeratIndex:0];
}
4.动画
//图层直线的轨迹
UIBezierPath*path = [UIBezierPathbezierPath];
[pathmoveToPoint:CGPointMake(0,0)];
[pathaddLineToPoint:CGPointMake(_animationView.frame.size.width,0)];
_progressLayer.path= path.CGPath;
self.progressLayer.strokeEnd=0.0;
//动画时间
CGFloatduration =_animationTime;
//进度程度
CGFloatprogress =_percent;
//strokeEnd动画到某个点结束
CABasicAnimation*animate = [CABasicAnimationanimationWithKeyPath:@"strokeEnd"];
animate.removedOnCompletion=NO;
animate.fillMode=kCAFillModeForwards;
animate.duration= duration;
animate.fromValue=@0.0;
#warning存在偏差,目前不知道原因
animate.toValue=@(progress-0.02);
//为图层添加动画
[self.progressLayeraddAnimation:animateforKey:@"anim1"];
//百分比标签动画(iOS 10在layoutSubView中失效???)
_percentView.center=CGPointMake(0,_percentView.center.y);
#warning此处使用延迟,使动画生效了
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
[UIViewanimateWithDuration:_animationTimeanimations:^{
_percentView.center=CGPointMake(self.frame.size.width*_percent,_percentView.center.y);
}];
});
阅读全文
0 0
- iOS绘图CALayer、UIBezierPath运用(边框、填充、复制、渐变)
- IOS学习 绘图 UIBezierPath 绘基本图形、样式设置、渲染填充
- 十二、Qt 2D绘图(二)渐变填充
- iOS CAShapeLayer和UIBezierPath绘图
- IOS学习 绘图 UIBezierPath 绘饼状图
- iOS---实现在屏幕上实时绘图的简单效果---CAShaperLayer和UIBezierPath的简单运用
- coreldraw 复制填充渐变色
- Swift-Core Graphics绘图框架详解3(绘制渐变、填充渐变色)
- Qt 2D绘图 渐变填充
- Qt笔记之绘图渐变填充
- 【iOS学习】三、利用UIBezierPath绘图
- iOS绘图-UIBezierPath的使用
- UIBezierPath绘图
- 绘图 UIBezierPath
- iOS(总结)绘图&渐变&NStimer
- [Qt教程] 第12篇 2D绘图(二)渐变填充
- iOS有关图片处理的总结 (五)------iOS绘图(UIBezierPath)
- iOS开发系列-动画绘图CALayer
- 编译原理词法分析小程序的设计
- 利用x64_dbg破解一个最简单的64位小程序
- 框架配置----Struts2
- SVO、LSD分析
- 孩子们的游戏(圆圈中最后剩下的数)
- iOS绘图CALayer、UIBezierPath运用(边框、填充、复制、渐变)
- Deep Residual Learning for Image Recognition(ResNet)论文笔记
- 【AngularJS2】Angular核心模块介绍
- android之ION内存管理器(1)-- 简介
- SpringMVC @RequestParam 中文乱码问题解决
- 冈萨雷斯数字图像处理学习1:绪论
- 远程桌面端口修改.bat
- mybatis—foreach标签使用小记
- SPOJ-227 ORDERS