听说你想做个饼状图(iOS)

最近项目需求,做了一个饼状图,整体效果还可以接受,故拿出来和大家分享一下,并希望能得到大神的一些改进建议或者意见~~

先上效果图:

all.gif

下面简单梳理一下整体的流程:

第一步:新建一个继承于UIView的文件。

此时我们需要这几样东西:

(1)数据源(区分比率)。

(2)颜色源(视觉信息)。

(3)标题源(文本信息)。

第二步:拿到数据源之后开始处理数据,算出各个数据的占比。

第三步:选定圆心,使用BezierPath来画圆并填充颜色。

需要注意的事:

(1)开始的弧度为-π/2,也就是从圆的顶部开始。

(2)第n个圆弧开始的弧度为第n-1个圆弧结束的弧度

(3)圆弧的弧度取自数据源对应项的比率*2π

此时我们能得到这样的效果:

饼状图

第四步:我们要做一些友好的展示效果——动画

动画是通过maskLayer的strokeEnd做改变来实现动画效果的。

核心的一张图:

maskLayer的构造

maskLayer的path是这样构造的,实际是红色的弧线,但是lineWidth(宽度)为圆饼的半径,这样我们就可以覆盖整个饼状图了,并可以通过控制strokeEnd来动画展示饼状图了。

第五步:点击效果

有了动画之后的饼状图用户感觉会好很多了,如果再加上交互,用户可以点击的话,那样就更棒了。

点击之后的处理是最关键的,贴上代码:

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    //不能点击则不做处理了
    if (!self.canClick) {
        return;
    }
    
    CGPoint touchPoint = [[touches anyObject] locationInView:self];
    for (CustomShapeLayer *shapeLayer in pieShapeLayerArray) {
        
        //如果只有一个模块,那么动画就要变化了,不是简单的偏移了
        if (self.segmentDataArray.count == 1) {
            shapeLayer.isOneSection = YES;
        }
        
        //判断选择区域
        shapeLayer.clickOffset =  [self preferGetUserSetValue:self.clickOffsetSpace withDefaultValue:15];

        if (CGPathContainsPoint(shapeLayer.path, 0, touchPoint, YES)) {
            
            //修改选中状态
            if (shapeLayer.isSelected) {
                
                shapeLayer.isSelected = NO;
            }else{
                shapeLayer.isSelected = YES;
                
            }
            
            NSInteger index = [pieShapeLayerArray indexOfObject:shapeLayer];
            
            //执行block并开始右侧小圆点动画
            [self dealClickCircleWithIndex:index];
            

        } else {
            
            shapeLayer.isSelected = NO;
        }
    }
}

点击时,我们根据isSelected做不同的处理,YES时,表示被选中,然后该模块的饼状图移动出来,移动的动画使用CABasicAnimation对path做处理;NO时,表示恢复原位,将该模块的饼状图复原。需要注意的是当你点击A块时,A被移动出来,此时点击B块,则B块移动出来的同时,A也要恢复回去。

关键处理的代码:

  if (isSelected) {
        //center 往外围移动一点 使用cosf跟sinf函数
        newCenterPoint = CGPointMake(_centerPoint.x + cosf((_startAngle + _endAngle) / 2) * offset, _centerPoint.y + sinf((_startAngle + _endAngle) / 2) * offset);
    }
    //创建一个path
    UIBezierPath *path = [UIBezierPath bezierPath];
    //起始中心点改一下
    [path moveToPoint:newCenterPoint];
    [path addArcWithCenter:newCenterPoint radius:_radius startAngle:_startAngle endAngle:_endAngle clockwise:YES];
    [path addArcWithCenter:newCenterPoint radius:_innerRadius startAngle:_endAngle endAngle:_startAngle clockwise:NO];
    [path closePath];
    self.path = path.CGPath;
    
    //添加动画
    CABasicAnimation *animation = [CABasicAnimation animation];
    //keyPath内容是对象的哪个属性需要动画
    animation.keyPath = @"path";
    //所改变属性的结束时的值
    animation.toValue = path;
    //动画时长
    animation.duration = 0.35;
    //添加动画
    [self addAnimation:animation forKey:nil];

至此流程的简单梳理已经完毕了,难度并不大,就是比较费心思而已。

如有疏漏不足,还请大神们多多指教~

共同进步,么么哒~

最后附上完整的代码地址:
完整代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容