swift自定義直方圖

先放預(yù)覽結(jié)果圖:


image.gif

以及swift文件:


xcode

接下來直接貼代碼加注釋:HistogramView.swift

import UIKit

class HistogramView: UIView {

    init(frame: CGRect, arrayValue:[CGFloat]) {
        super.init(frame: frame)
        //創(chuàng)建直方圖的方法, arrayValue為創(chuàng)建直方圖時傳進(jìn)來的數(shù)組婿着,就是直方圖應(yīng)該顯示的值
        createHistogram(arrayValue: arrayValue)
    }
    //畫底部的線蝴蜓,左右間距10搀菩,下部間距9
    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else {
            return
        }
        let drawingRect = bounds
        let path = CGMutablePath()
        path.move(to: CGPoint(x: 10, y: drawingRect.height-9))
        path.addLine(to: CGPoint(x: drawingRect.width-10, y: drawingRect.height-9))
        context.setStrokeColor(UIColor.black.cgColor)
        context.addPath(path)
        context.strokePath()
    }
    
    //創(chuàng)建直方圖
    func createHistogram(arrayValue:[CGFloat]){
        //取到數(shù)組的最大值最小值
        let value = minMax(arr: arrayValue)
        //設(shè)置直方圖最大高度為bounds.height - 40严沥,距底部10熟嫩,距頂部30片习,用這個高度除以最大值來計算每一個值的單位高度
        let unitHeight = (bounds.height - 40) / CGFloat(value.1)
        let scrollView = UIScrollView(frame: CGRect(x: 10, y: 0, width: bounds.width-20, height: bounds.height))
        scrollView.showsVerticalScrollIndicator = false
        scrollView.showsHorizontalScrollIndicator = false
        //根據(jù)顯示內(nèi)容的多少來設(shè)置scrollView的contentSize
        let ContentSizeWidth = (40 * CGFloat(arrayValue.count) + 20) > scrollView.bounds.width ? (40 * CGFloat(arrayValue.count) + 20) : scrollView.bounds.width
        scrollView.contentSize = CGSize(width: ContentSizeWidth, height: bounds.height-10)

         //創(chuàng)建每一個直方圖
        for i in 0 ..< arrayValue.count {
            //高度為實際值*單位高度
            let height = arrayValue[i] * unitHeight
            //寬度為40照卦,左右間距為10
            let x = 40.0*CGFloat(i)+10
            //底部間距為10
            let y = bounds.height - 10 - height
            let rectView = UIView(frame: CGRect(x: x, y: y, width: 30.0, height: height))
            rectView.backgroundColor =  UIColor.blue
            scrollView.addSubview(rectView)
            
            //高度的動畫效果
            let rotationAnim = CABasicAnimation(keyPath: "bounds")
            rotationAnim.repeatCount = 1
            rotationAnim.duration = 1
            rotationAnim.fromValue = NSValue(cgRect: CGRect(x: 0, y: 0, width: rectView.bounds.width, height: 0))
            rotationAnim.toValue = NSValue(cgRect: rectView.bounds)
            rectView.layer.add(rotationAnim, forKey: "bounds")

             //高度的動畫效果,不設(shè)置這個位移動畫的話高度動畫會從y的中點開始而不是從底部開始
            let rotationAnim2 = CABasicAnimation(keyPath: "position")
            rotationAnim2.repeatCount = 1
            rotationAnim2.duration = 1
            rotationAnim2.fromValue = NSValue(cgPoint: CGPoint(x: rectView.center.x, y: bounds.height - 10))
            rotationAnim2.toValue = NSValue(cgPoint: rectView.center)
            rectView.layer.add(rotationAnim2, forKey: "position")

            //設(shè)置UILabel來顯示具體值
            let text = UILabel(frame: CGRect(x: x, y: y-15, width: 30.0, height: 14.0))
            text.text = "\(NSInteger(arrayValue[i]))"
            text.font = UIFont.systemFont(ofSize: 12)
            text.textAlignment = .center
            scrollView.addSubview(text)

            //UILabel的位移動畫狸驳,和直方圖一起上升
            let rotationAnim3 = CABasicAnimation(keyPath: "position")
            rotationAnim3.repeatCount = 1
            rotationAnim3.duration = 1
            rotationAnim3.isRemovedOnCompletion = false
            rotationAnim3.fromValue = NSValue(cgPoint: CGPoint(x: text.center.x, y: bounds.height - 17))
            rotationAnim3.toValue = NSValue(cgPoint: text.center)
            text.layer.add(rotationAnim3, forKey: "position")
        }
        
        self.addSubview(scrollView)
        
    }
    //獲取數(shù)組最大值和最小值
    func minMax(arr:[CGFloat])->(CGFloat,CGFloat) {
        var min:CGFloat = arr[0]
        var max:CGFloat = arr[0]
        for i in 0..<arr.count {
            if arr[i] < min {
                min = arr[i]
            }
            if arr[i] > max {
                max = arr[i]
            }
        }
        return (min,max)
    }

    required init?(coder _: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

使用方式

 override func viewDidLoad() {
        super.viewDidLoad()
        let array : [CGFloat] = [100,200,150,75,20,50,60,130,110,190,40,55,23,99]
        self.view.backgroundColor = UIColor.white
        let view = HistogramView(frame: CGRect(x: 10, y: 100, width: self.view.frame.width-20, height: 200), arrayValue: array)
        view.backgroundColor = UIColor.green
        view.tag = 1001
        self.view.addSubview(view)
        
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末预明,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子耙箍,更是在濱河造成了極大的恐慌撰糠,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辩昆,死亡現(xiàn)場離奇詭異阅酪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)汁针,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門术辐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人扇丛,你說我怎么就攤上這事术吗∥炯” “怎么了帆精?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長隧魄。 經(jīng)常有香客問我卓练,道長,這世上最難降的妖魔是什么购啄? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任襟企,我火速辦了婚禮,結(jié)果婚禮上狮含,老公的妹妹穿的比我還像新娘顽悼。我一直安慰自己曼振,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布蔚龙。 她就那樣靜靜地躺著冰评,像睡著了一般。 火紅的嫁衣襯著肌膚如雪木羹。 梳的紋絲不亂的頭發(fā)上甲雅,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機(jī)與錄音坑填,去河邊找鬼抛人。 笑死,一個胖子當(dāng)著我的面吹牛脐瑰,可吹牛的內(nèi)容都是我干的妖枚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蚪黑,長吁一口氣:“原來是場噩夢啊……” “哼盅惜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起忌穿,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤抒寂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后掠剑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屈芜,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年朴译,在試婚紗的時候發(fā)現(xiàn)自己被綠了井佑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡眠寿,死狀恐怖躬翁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盯拱,我是刑警寧澤盒发,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站狡逢,受9級特大地震影響宁舰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奢浑,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一蛮艰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雀彼,春花似錦壤蚜、人聲如沸即寡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嘿悬。三九已至,卻和暖如春水泉,著一層夾襖步出監(jiān)牢的瞬間善涨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工草则, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留钢拧,地道東北人。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓炕横,卻偏偏與公主長得像源内,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子份殿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 2018.3.19 李敖的離世膜钓,讓世界少了一個桀驁不馴的斗士!
    謙謙闋歌閱讀 99評論 0 0
  • 今天的工作效率并不高卿嘲。 坐上了地鐵颂斜,才發(fā)現(xiàn)原來自己到了智力狀態(tài)低谷期。 怪不得難以集中注意力拾枣,還把今天應(yīng)該寫的挑戰(zhàn)...
    左葉右李閱讀 224評論 0 1
  • 劉彥 焦點講師一期 焦作 堅持原創(chuàng)分享第898天+堅持運動第111天】 2019.6.17周一 前天的案例分享來自...
    你若盛開彥閱讀 586評論 0 7