對于iOS柱狀圖窿祥,不是有什么難度的效果株憾,gayhub上也有很多優(yōu)秀的第三方庫,比如AAChartKit
晒衩、XYPieChart
嗤瞎、PNChart
、Charts
等好多听系,不過這些類庫大多封裝的太厲害了贝奇,如果你的項目只是單純的幾個柱狀圖、那么使用這些庫其實挺費勁的(學(xué)習(xí)成本+項目大锌渴ぁ)掉瞳,下面說說我的思路。
iOS繪圖以及圖形處理主要使用的是Core Graphics
/QuartZ 2D
浪漠,這也是大部分人寫柱狀圖的方法陕习,即使用UIBezierPath
配合Core Graphics
實現(xiàn)。我的思路是使用UICollectionView
址愿,不過使用UICollectionView
實現(xiàn)柱狀圖衡查,最好需求能滿足以下二點:
- 1.柱狀圖的柱子夠?qū)挘詈糜悬c擊需求
- 2.柱狀圖的柱子比較多必盖,需要滑動,這個更能體現(xiàn)出Cell復(fù)用
當然俱饿,也并不是一定要滿足上面2點歌粥,接下來用幾個小Demo演示一下(注:Demo是Objective-C實現(xiàn))
DemoA
這個是基本的效果,使用UICollectionViewFlowLayout
布局拍埠,將scrollDirection
設(shè)置為UICollectionViewScrollDirectionHorizontal
失驶;每個cell
內(nèi)部有個綠色的UIView
,根據(jù)數(shù)值調(diào)整這個綠色UIView
的高度枣购,就是圖上的效果了嬉探,其實核心就是UICollectionViewFlowLayout
,后面幾個Demo也全是基于此棉圈。
UICollectionViewFlowLayout *fw = [[UICollectionViewFlowLayout alloc] init];
fw.scrollDirection = UICollectionViewScrollDirectionHorizontal;
fw.minimumLineSpacing = 10;
fw.minimumInteritemSpacing = 0;
fw.itemSize = CGSizeMake(220, 30);
fw.headerReferenceSize = CGSizeMake(10, 220);
fw.footerReferenceSize = CGSizeMake(10, 220);
DemoB
這個效果是加了橫坐標值和漸變Cell涩堤,每個柱狀圖重新出現(xiàn)屏幕上時,會動畫出現(xiàn)分瘾,需要注意的是胎围,漸變使用的是CAGradientLayer
,但是對含有CAGradientLayer
的view使用frame
動畫,會造成漸變的卡頓和動畫的不流暢白魂,所以這里是使用CAGradientLayer
生成一張漸變圖汽纤,設(shè)置成柱狀圖柱子的背景即可。
DemoC
這個效果是始終以中間的Cell為基準顯示福荸,點擊其他Cell也會自動滾到中心蕴坪。因為UICollectionView
繼承于UIScrollView
,所以實現(xiàn)這種效果敬锐,關(guān)鍵在于兩個代理方法:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset;
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
具體的原理背传,可以查看這篇優(yōu)秀的文章:UIScrollView 實踐經(jīng)驗
DemoD
這個效果的目的是:有的需求是柱狀圖比較密集,當手指滑動時又要求可以顯示出對應(yīng)柱子的值滞造。其實實現(xiàn)起來很簡單续室,就是使用touchesBegan:withEvent:
以及touchesMoved:withEvent:
等幾個方法即可。
DemoE
這個是有柱狀圖的同時谒养,還有曲線圖挺狰,實現(xiàn)方法是在UICollectionView
上面加了一個透明的UIView
,同時通過此UIView
的hitTest:withEvent:
方法买窟,將事件給到UICollectionView
丰泊,再通過UICollectionView
的代理方法,獲取界面上的Cell始绍,繪制曲線到UIView
上瞳购。需要注意的是,UICollectionView
的visibleCells
方法亏推,獲取到的Cell学赛,順序不是界面上的順序,需要排序之后再使用吞杭。
其實通過UIView
的hitTest:withEvent:
方法盏浇,能做很多神奇的事情,大家可以自行研究芽狗。
DemoF
這個沒啥绢掰,就是說明如果有復(fù)雜的坐標,也是可以實現(xiàn)的童擎,這個Demo的做法是在UICollectionView
下面有一個UIView
專門繪制坐標系滴劲。
DemoG
這個其實跟柱狀圖沒有關(guān)系,大家都知道顾复,安卓的刷新和iOS不一樣班挖,下拉刷新分為侵入式和非侵入式,對于iOS而言捕透,由于UIScrollView
的Bounce
效果聪姿,所以使用侵入式下拉刷新碴萧,成了最好的選擇,但是iOS能否實現(xiàn)安卓那樣的非侵入式刷新呢末购?于是本Demo就簡單研究了一下破喻,目前是存在bug的,樣式也粗糙盟榴,不過思路應(yīng)該沒有問題曹质,提供給大家,可以研究研究:
1. 添加 UITableView
2. 在TableView上覆蓋一個無背景色的UIScrollView
3. 覆寫UIScrollView的幾個touchesBegan擎场、touchesEnded等幾個方法羽德,使其點擊事件傳遞到TableView
4. 在UIScrollView的代理方法scrollViewDidScroll里處理
4.1 scrollView.contentOffset.y小于0,處理刷新動畫和刷新邏輯
4.2 scrollView.contentOffset.y大于0迅办,同步設(shè)置TableView的contentOffset 來保持滾動一致
5. 應(yīng)該始終讓scrollView和TableView的contentSize保持一致
至此宅静,本文就沒了,其實本文沒啥技術(shù)含量站欺,說白就是UICollectionView
的使用姨夹,不過主要目的是給大家提供思路,具體需求還得具體分析矾策。
本文Demo地址:GitHub
END磷账。
我是小侯爺。
在帝都艱苦奮斗贾虽,白天是上班族逃糟,晚上是知識服務(wù)工作者。
如果讀完覺得有收獲的話蓬豁,記得關(guān)注和點贊哦绰咽。
非要打賞的話,我也是不會拒絕的地粪。