iOS 自定義進度條

一般成長值類型的進度條都是純色的贩幻,比如這樣的:


keep等級進度條

純色的進度條無論用layer還是view,只要計算好比例就是很好做的峭火。

我們的需求是自定義的進度條是這樣的:


屏幕快照 2019-07-30 下午9.24.25.png

從圖中可以看出我們的UI進度條是紅粉相間的被芳,而且單個的還是平行四邊形襟企。在實現方案上肪获,考慮了下寝凌,就放棄了使用切圖imageView實現的思路,因為進度條的長度代表當前值和總值的比例孝赫,就算是平行四邊形也有可能不是完整的四邊形较木,使用切圖的方式是不好實現的。那么我們只能通過layer來實現了寒锚。

確定了基本的方案劫映,還有幾個問題:
1.如何實現粉紅相間的效果
2.如何繪制每個平行四邊形、進度條末端不完整的四邊形以及進度條最后的弧線
3.這么大的圖標占了一小段的進度條怎么辦
4.怎么知道進度條要畫多長刹前,平行四邊形要畫多少個,以及進度條末端不完整的四邊形的大小

現在我們來一一解答這些問題:

1.純色的進度條可以很容易的用layer實現雌桑,但是多個顏色的不容易實現喇喉,是因為layer只能有一種fillColor或者strokeColor,設置兩種fillColor或者strokeColor會以最后的設置來繪制。我也想過把紅色校坑、粉色分別作為fillColor和strokeColor,但是想想就放棄了拣技,路徑實現不好畫。那我們如果用兩個layer分別是粉色耍目、紅色的fillColor是不是就可以實現了膏斤?理論上是可以的。

- (CAShapeLayer *)redLayer
{
    if (!_redLayer) {
        _redLayer = [CAShapeLayer layer];
        _redLayer.fillColor = HKColor(252, 85, 108, 1).CGColor;
        _redLayer.strokeColor = HKColor(255, 153, 167, 1).CGColor;

        _redLayer.lineWidth = 1;
        
    }
    return _redLayer;
}

- (CAShapeLayer *)pinkLayer
{
    if (!_pinkLayer) {
        _pinkLayer = [CAShapeLayer layer];
        _pinkLayer.fillColor = HKColor(255, 153, 167, 1).CGColor;
        _pinkLayer.strokeColor = HKColor(255, 153, 167, 1).CGColor;
        _pinkLayer.lineWidth = 1;


    }
    return _pinkLayer;
}

2.四邊形可以看做是一條條直線組成邪驮,弧線可以用半圓來近似繪制,這兩種繪制都可以用貝塞爾曲線很容易的實現莫辨,如下所示:


            [path moveToPoint:CGPointMake(0+_singleSquareWidth*(i-1), _singleSquareHeight)];
            [path addLineToPoint:CGPointMake(0+_singleSquareOffset+_singleSquareWidth*(i-1), 0)];
            [path addLineToPoint:CGPointMake(0+_singleSquareOffset+_singleSquareWidth*(i-1)+_singleSquareWidth,0)];
            [path addLineToPoint:CGPointMake(0+_singleSquareWidth+_singleSquareWidth*(i-1),_singleSquareHeight)];
            [path addLineToPoint:CGPointMake(0+_singleSquareWidth*(i-1), _singleSquareHeight)];
            [redPath addArcWithCenter:CGPointMake(0, _singleSquareHeight/2) radius:_singleSquareHeight/2 startAngle:M_PI_2 endAngle:M_PI_2*3 clockwise:YES];

這兩種都是貝塞爾曲線的基本用法

3.由于我們的圖標比較大,所以占據的進度條的長度是不可以忽略不計的,所以我們需要圖標占位大小一個值沮榜,方便我們做進度條進度的比例剔除掉這部分的長度盘榨,避免出現進度條進度和進度值不符的現象。

4.要確定進度條畫多長我們要先確定蟆融,進度值是在當前哪一段進度中草巡,就是我的代碼中定義的index屬性,從0開始型酥。

if (self.currentGrowUpValue == [[self.growUpValueArray firstObject] integerValue]) {
        self.index = 0;
        return;
    }
    for (NSInteger i = 0;i<self.growUpValueArray.count ; i++) {
        NSInteger indexValue = [self.growUpValueArray[i] integerValue];
        
        
        if (self.currentGrowUpValue >= indexValue) {
            self.index = i;
        }else{
            return;
        }
        
        
    }

確定了index之后我們再確定進度條的長度山憨,如果進度值為0我們是不繪制進度條的,進度值等于最大值就是繪制滿進度條弥喉,其他情況需要按比例計算進度條長度萍歉。

    if (self.index == self.growUpValueArray.count - 1) {
        
        self.processLayerWidth = _lineWidth;
    }else{
        
        CGFloat lastScale = (CGFloat)(self.currentGrowUpValue - [self.growUpValueArray[self.index] integerValue])/(CGFloat)([self.growUpValueArray[self.index+1] integerValue]- [self.growUpValueArray[self.index] integerValue]);
        self.processLayerWidth = (self.singleLineWidth + self.iconPlaceHolderPT)*self.index + self.singleLineWidth*lastScale+self.iconPlaceHolderPT/2 - (lastScale == 0? self.iconPlaceHolderPT/2:0);
    }


這里進度條的計算是最核心的部分,我的繪制原則是如果lastScale是0档桃,就繪制到占位的圖標中心位置結束枪孩,如果lastScale>0,要從占位圖標的最右側開始繪制,這就是我再上面說的藻肄,剔除掉占位圖標的大小蔑舞,不能算做計算進度比例的基數,也不能算作長度嘹屯,之所以lastScale = 0攻询,要繪制到占位圖標中心,是因為占位圖標多數有透明背景州弟,只繪制到圖標左側有進度不滿的既視感钧栖。

有了進度條的長度我們就很好計算平行四邊形的個數了

    NSInteger singleCount = _processLayerWidth/self.singleSquareWidth;

大家都能明白這里是不能整除的,剩下的部分就是進度條末端的長度了婆翔,然后再加上個半圓就完成了

    [path moveToPoint:CGPointMake(_layerLeft+(singleCount-1)*self.singleSquareWidth + self.singleSquareOffset, +_layerTop)];
    [path addLineToPoint:CGPointMake(_layerLeft+_processLayerWidth, +_layerTop)];
    [path addArcWithCenter:CGPointMake(_layerLeft+_processLayerWidth, _singleSquareHeight/2+_layerTop) radius:_singleSquareHeight/2 startAngle:-M_PI_2 endAngle:M_PI_2 clockwise:YES];
    
    [path addLineToPoint:CGPointMake(_layerLeft+(singleCount-1)*self.singleSquareWidth, _singleSquareHeight+_layerTop)];

方案二:切整個紅粉相間的進度條的圖拯杠,然后黃色部分動態(tài)繪制剩下長度的layer
這種比較簡單,就不用貼代碼了啃奴。

這里是GitHub地址:https://github.com/SunshineTeemo/SSCustomProcessView/tree/master
請大家多指教潭陪!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市最蕾,隨后出現的幾起案子依溯,更是在濱河造成了極大的恐慌,老刑警劉巖瘟则,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件黎炉,死亡現場離奇詭異,居然都是意外死亡醋拧,警方通過查閱死者的電腦和手機慷嗜,發(fā)現死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門淀弹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人洪添,你說我怎么就攤上這事垦页。” “怎么了干奢?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵痊焊,是天一觀的道長。 經常有香客問我忿峻,道長薄啥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任逛尚,我火速辦了婚禮垄惧,結果婚禮上,老公的妹妹穿的比我還像新娘绰寞。我一直安慰自己到逊,他們只是感情好,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布滤钱。 她就那樣靜靜地躺著觉壶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪件缸。 梳的紋絲不亂的頭發(fā)上铜靶,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機與錄音他炊,去河邊找鬼争剿。 笑死,一個胖子當著我的面吹牛痊末,可吹牛的內容都是我干的蚕苇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼舌胶,長吁一口氣:“原來是場噩夢啊……” “哼捆蜀!你這毒婦竟也來了?” 一聲冷哼從身側響起幔嫂,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎誊薄,沒想到半個月后履恩,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡呢蔫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年切心,在試婚紗的時候發(fā)現自己被綠了飒筑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡绽昏,死狀恐怖协屡,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情全谤,我是刑警寧澤肤晓,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站认然,受9級特大地震影響补憾,放射性物質發(fā)生泄漏。R本人自食惡果不足惜卷员,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一盈匾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧毕骡,春花似錦削饵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至橱赠,卻和暖如春尤仍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狭姨。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工宰啦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人饼拍。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓赡模,卻偏偏與公主長得像,于是被迫代替她去往敵國和親师抄。 傳聞我的和親對象是個殘疾皇子漓柑,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內容

  • 一、為啥要自定義進度條叨吮? 系統(tǒng)的不好用辆布、系統(tǒng)的不好用、系統(tǒng)的不好用茶鉴,說了三遍心里爽多了锋玲。具體怎么不好用?無法設置高...
    擼代碼我是認真的閱讀 7,871評論 0 3
  • 前言 我們在自定義進度條的時候,會遇到各種各樣的樣式,有在視圖中加載的,也有放在外面的涵叮。通常這種時候有部分人會選擇...
    神SKY閱讀 2,165評論 3 2
  • 1. 創(chuàng)建MTProcessView, 并繼承自UIButton MTProcessView.h MTProces...
    _凌浩雨閱讀 4,650評論 0 1
  • 1 CALayer IOS SDK詳解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi閱讀 5,150評論 3 23
  • 每個UIView有一個伙伴稱為layer惭蹂,一個CALayer伞插。UIView實際上并沒有把自己畫到屏幕上;它繪制本身...
    shenzhenboy閱讀 3,107評論 0 17