天天看點

iOS 開源圖形庫 Core Plot 使用教程

<b>本文講的是iOS 開源圖形庫 Core Plot 使用教程,</b>

iOS 開源圖形庫 Core Plot 使用教程

注意 :本篇教程已被 Attila Hegedüs 更新,可适用于 iOS 9 和 Swift 2.2。原始教程出自教程組成員 Steve Baranski。

如果你曾經想在自己的 app 中引入圖表或圖形,那麼你應該已經考慮過下面兩種選項:

自己寫。 通過使用 Core Graphics 或者 Quartz 這樣的架構編寫全部的繪制代碼。然而,這顯然要花費大量的功夫。

Core Plot 是一個2D繪制庫,适用于 iOS,Mac OS X 和 tvOS。它使用了像 Quartz 和 Core Animation 這樣的蘋果應用架構,同時有着全面的測試覆寫,而且是遵照BSD這個比較寬松的許可證進行釋出的。

在這個教程中,你将學習到如何使用 Core Plot 來建立餅圖和柱狀圖,同時還會實作一些很酷的圖表互動!

項目的關鍵類在 App 這個檔案夾和它的子檔案夾下,它們包括了:

DataStore.swift

Rate.swift

這是一個模型,表示給定日期裡的貨币匯率。

Currency.swift

這是一個表示貨币類型的模型。支援的貨币類型定義在 Resources/Currencies.plist 裡。

MenuViewController.swift

這是一個app啟動後展示的第一個視圖控制器。它讓使用者選擇一個貨币作為基準然後再選兩個對照。

HostViewController.swift

這是一個容器視圖控制器,基于它的分段選項選中狀态去控制展示 <code>PieChartViewController</code> 或者<code>BarGraphViewController</code> 的内容。它還會去檢查從 <code>DataStore</code> 請求來的匯率資料,因為它們也将在這個視圖控制器裡展現。

PieChartViewController.swift

這個控制器将用餅圖的形式展示一個給定日期裡的匯率。當然你首先要實作它!

BarGraphViewController.swift

這個控制器将以柱狀圖的形式展示幾天的匯率。當你掌握繪制餅圖的方法後,這個圖簡直小菜一碟!(看到我做的事情了嗎?拜托,這真的有點意思!);]

建構并運作看看這個教程入門項目實際展示。

iOS 開源圖形庫 Core Plot 使用教程

點選 Get Rates 導航去到 <code>HostViewController</code> 控制的視圖然後可以切換分段選項。這個 app 确實還沒有實作太多功能…;]

是時候用 Core Plot 開始真正的繪制了!

把下面這行代碼添加進你的 Podfile 檔案, <code>pod 'SwiftDate'</code> 這行的後面:

打開 Terminal (終端),<code>cd</code> 進入你的項目根目錄,然後運作 <code>pod install</code>。

安裝完成後,建構項目。

沒報錯吧?很好,現在你可以随便使用 Core Plot 啦,感謝 CocoaPods。:]

如果你遇到了任何報錯,可以嘗試通過 <code>sudo gem install cocoapods</code> 更新一下 CocoaPods 然後再次運作<code>pod install</code>。

打開 PieChartViewController.swift 并添加下面這行引入:

1

import CorePlot

接着,添加下面這個屬性:

@IBOutlet weak var hostView: CPTGraphHostingView!

<code>CPTGraphHostingView</code> 負責“托管”一個圖表或圖形。你可以把它想象成一個“圖形容器”。

然後,把下面這個類擴充添加到檔案結尾的花括号之後:

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

extension PieChartViewController: CPTPieChartDataSource, CPTPieChartDelegate {

func numberOfRecordsForPlot(plot: CPTPlot) -&gt; UInt {

return 0

}

func numberForPlot(plot: CPTPlot, field fieldEnum: UInt, recordIndex idx: UInt) -&gt; AnyObject? {

func dataLabelForPlot(plot: CPTPlot, recordIndex idx: UInt) -&gt; CPTLayer? {

return nil

func sliceFillForPieChart(pieChart: CPTPieChart, recordIndex idx: UInt) -&gt; CPTFill? {

func legendTitleForPieChart(pieChart: CPTPieChart, recordIndex idx: UInt) -&gt; String? {

你将通過 <code>CPTPieChartDataSource</code> 為一個 Core Plot 圖表提供資料,同時你會通過 <code>CPTPieChartDelegate</code> 得到使用者互動的所有事件。随着教程遞進,你将填滿這些方法。

繼續往下,打開 Main.storyboard 然後選擇 <code>PieChartViewController</code> 視窗。

在這個視圖上拖出一個新的 <code>UIView</code>,然後把它的類更改成 <code>CPTGraphHostingView</code>,并将它連接配接到 <code>hostView</code>。

對這個視圖的每個方向添加限制讓撐滿父視圖,并确認沒有設定外邊距的限制:

iOS 開源圖形庫 Core Plot 使用教程

設定一個你喜歡的背景色。我使用了透明度為92%的灰階顔色。

現在回到 PieChartViewController.swift ,在 <code>viewDidLoad()</code> 後面添加下面的方法:

23

override func viewDidLayoutSubviews() {

super.viewDidLayoutSubviews()

initPlot()

func initPlot() {

configureHostView()

configureGraph()

configureChart()

configureLegend()

func configureHostView() {

func configureGraph() {

func configureChart() {

func configureLegend() {

這樣子就正好在子視圖渲染好後設定了繪制政策。這裡是你最早為視圖設定架構大小的地方,接下來你将需要配置繪制政策。

<code>initPlot()</code> 裡的每個方法都代表了一個設定繪制政策的階段。這樣子可以讓代碼保持其可維護性。

把下面這行添加進 <code>configureHostView()</code>:

hostView.allowPinchScaling = false

這行代碼将對餅圖禁用手勢捏合縮放,它決定了托管視圖對捏合手勢是否會有反應。

接下來你需要添加一個圖表到<code>hostView</code>。添加下面的代碼到 <code>configureGraph()</code> 裡吧:

// 1 - Create and configure the graph

let graph = CPTXYGraph(frame: hostView.bounds)

hostView.hostedGraph = graph

graph.paddingLeft = 0.0

graph.paddingTop = 0.0

graph.paddingRight = 0.0

graph.paddingBottom = 0.0

graph.axisSet = nil

// 2 - Create text style

let textStyle: CPTMutableTextStyle = CPTMutableTextStyle()

textStyle.color = CPTColor.blackColor()

textStyle.fontName = "HelveticaNeue-Bold"

textStyle.fontSize = 16.0

textStyle.textAlignment = .Center

// 3 - Set graph title and text style

graph.title = "\(base.name) exchange rates\n\(rate.date)"

graph.titleTextStyle = textStyle

graph.titlePlotAreaFrameAnchor = CPTRectAnchor.Top

下面對每個部分的代碼進行分解:

首先你建立了一個 <code>CPTXYGraph</code> 的執行個體并指定它作為 <code>hostView</code> 的 <code>hostedGraph</code>。這就将圖表和托管視圖聯系起來了。

這個 <code>CPTGraph</code> 包括了你所看到的标準圖表或圖形的全部東西:邊,标題,繪制相關資料,軸和圖例。

預設情況下,<code>CPTXYGraph</code> 每個方向都有一個<code>20</code>的内邊距。從我們這個項目來看這樣并不好,是以你可以顯式地将每個方向的内邊距設定為<code>0</code>。

接下來就是通過建立和配置一個 <code>CPTMutableTextStyle</code> 執行個體來設定該圖示标題的文本樣式。

最後,就是給你剛剛建立的圖表執行個體設定标題和其樣式。同樣你還需要指定标題錨點為該視圖的上邊界。

建構并運作app,你應該就可以看到這個圖表的标題展示在螢幕上了:

iOS 開源圖形庫 Core Plot 使用教程

标題看起來不錯,但你知道接下來什麼會更棒嗎?确确實實地看到餅圖!

将下面的代碼添加進 <code>configureChart()</code>:

24

25

26

27

28

// 1 - Get a reference to the graph

let graph = hostView.hostedGraph!

// 2 - Create the chart

let pieChart = CPTPieChart()

pieChart.delegate = self

pieChart.dataSource = self

pieChart.pieRadius = (min(hostView.bounds.size.width, hostView.bounds.size.height) * 0.7) / 2

pieChart.identifier = graph.title

pieChart.startAngle = CGFloat(M_PI_4)

pieChart.sliceDirection = .Clockwise

pieChart.labelOffset = -0.6 * pieChart.pieRadius

// 3 - Configure border style

let borderStyle = CPTMutableLineStyle()

borderStyle.lineColor = CPTColor.whiteColor()

borderStyle.lineWidth = 2.0

pieChart.borderLineStyle = borderStyle

// 4 - Configure text style

let textStyle = CPTMutableTextStyle()

textStyle.color = CPTColor.whiteColor()

pieChart.labelTextStyle = textStyle

// 3 - Add chart to graph

graph.addPlot(pieChart)

```

下面看看這段代碼做了什麼:

首先擷取了剛剛建立的圖表的引用。

然後執行個體化一個 <code>CPTPieChart</code>,将它的代理和資料源設定成這個視圖控制器本身,并配置它的一些外觀屬性。

接着配置這個圖表的邊框樣式。

配置它的文本樣式。

最後,将這個餅圖添加進剛剛引用的圖表裡。

如果現在重新建構并運作 app,你将看不到任何變化…因為你還需要實作這個餅圖的代理和資料源。

首先,用下面這段替代了現在的 <code>numberOfRecordsForPlot(_:)</code> 方法:

return UInt(symbols.count) ?? 0

這個方法決定了有多少塊(部分)顯示在餅狀圖上,它将為每一個标記顯示一塊(部分)。

接下來,用下面這段替換掉 <code>numberForPlot(_:field:recordIndex:)</code> :

let symbol = symbols[Int(idx)]

let currencyRate = rate.rates[symbol.name]!.floatValue

return 1.0 / currencyRate

餅圖會使用這個方法得到索引為 <code>recordIndex</code> 的貨币符号的“總”值。

你應該注意到這個值并 不是 一個百分比值。取而代之的是,這個方法計算出了相對基準貨币的貨币匯率:傳回的這個<code>1.0 / currencyRate</code> 的值是”一個機關的基準貨币是多少價值的另外的對照貨币”的匯率。

<code>CPTPieChart</code> 将檢視計算每個分塊的百分比值,這個值最終決定了這個分塊占多大。

下面,用下面這行替代掉 <code>dataLabelForPlot(_:recordIndex:)</code> :

let value = rate.rates[symbols[Int(idx)].name]!.floatValue

let layer = CPTTextLayer(text: String(format: "\(symbols[Int(idx)].name)\n%.2f", value))

layer.textStyle = plot.labelTextStyle

return layer

這個方法傳回了餅圖分片的标簽。期望的傳回類型 <code>CPTLayer</code> 和 <code>CALayer</code> 有點相似,但是 CPTLayer 更加抽象,在 Mac OS X 和 iOS 上都能用,還提供了額外的繪圖細節供 Core Plot 使用。

這裡,建立并傳回一個 <code>CPTLayer</code> 的子類 <code>CPTTextLayer</code> 去展示文本。

最後,将下面這段代碼替換掉 <code>sliceFillForPieChart(_:, recordIndex:)</code> 去添加分片的顔色:

switch idx {

case 0: return CPTFill(color: CPTColor(componentRed:0.92, green:0.28, blue:0.25, alpha:1.00))

case 1: return CPTFill(color: CPTColor(componentRed:0.06, green:0.80, blue:0.48, alpha:1.00))

case 2: return CPTFill(color: CPTColor(componentRed:0.22, green:0.33, blue:0.49, alpha:1.00))

default: return nil

建構并運作,你就将看到一個漂亮的餅圖了:

iOS 開源圖形庫 Core Plot 使用教程

這個圖表看上去相當不錯,但是添加一個圖例應該會讓它更棒。接下來你将學習怎麼添加一個圖例到這個圖表裡。

首先,用下面這段替換掉 <code>configureLegend()</code>:

// 1 - Get graph instance

guard let graph = hostView.hostedGraph else { return }

// 2 - Create legend

let theLegend = CPTLegend(graph: graph)

// 3 - Configure legend

theLegend.numberOfColumns = 1

theLegend.fill = CPTFill(color: CPTColor.whiteColor())

textStyle.fontSize = 18

theLegend.textStyle = textStyle

// 4 - Add legend to graph

graph.legend = theLegend

if view.bounds.width &gt; view.bounds.height {

graph.legendAnchor = .Right

graph.legendDisplacement = CGPoint(x: -20, y: 0.0)

} else {

graph.legendAnchor = .BottomRight

graph.legendDisplacement = CGPoint(x: -8.0, y: 8.0)

同樣你也需要為每個分片提供圖例的資料。

要提供資料,就用下面這段替換掉 <code>legendTitleForPieChart(_:recordIndex:)</code>:

return symbols[Int(idx)].name

建構并運作,你就會得到一個“帶圖例的”圖表啦。

iOS 開源圖形庫 Core Plot 使用教程

看樣子你已經是繪制餅圖的專家啦,但是時候去搞一個柱狀圖了!

打開 <code>BarGraphViewController</code> 并添加下面這行:

接着,再添加下面這行:

@IBOutlet var hostView: CPTGraphHostingView!

其實就和餅圖一樣,托管視圖将承載這個柱狀圖的展示。

下一步,添加下面這些屬性:

var plot1: CPTBarPlot!

var plot2: CPTBarPlot!

var plot3: CPTBarPlot!

這裡聲明了三個 <code>CPTBarPlot</code> 類型的屬性,它們就相當于展示在圖表中的每種貨币。

注意到同樣也有三個 <code>IBOutlet</code> 标簽和三個 <code>IBAction</code> 方法已經被定義了,你都可以在 storyboard 上看到它們。

最後,把下面這個類擴充添加到檔案末尾:

extension BarGraphViewController: CPTBarPlotDataSource, CPTBarPlotDelegate {

func barPlot(plot: CPTBarPlot, barWasSelectedAtRecordIndex idx: UInt, withEvent event: UIEvent) {

這和建立餅圖的過程太像了:通過 <code>CPTBarPlotDataSource</code> 為柱狀圖提供資料,通過 <code>CPTBarPlotDelegate</code> 捕捉使用者互動事件。你隻需要複制粘貼就好了。

就像剛剛建立餅圖時候一樣,再次需要通過界面生成器把托管視圖添加進去。

回到 Main.storyboard 并選擇 <code>BarGraphViewController</code> 視窗。

在視圖上拖拽出一個新的 <code>UIView</code>,将它的類更改為 <code>CPTGraphHostingView</code> 并将其輸出連接配接到控制器裡的<code>hostView</code>。

通過 Utilities\Size Inspector (那個 刻度尺 頁籤)将它的架構更新到下面那樣:

X = 0, Y = 53, Width = 600, Height = 547

iOS 開源圖形庫 Core Plot 使用教程

添加它和所有相鄰元素的限制,确認沒有設定 外邊距限制 。

iOS 開源圖形庫 Core Plot 使用教程

最後,設定一個你喜歡的背景顔色。我再次用了92%透明度的灰階顔色。

既然 UI 已經通過上面的學習全部弄好了,是時候去繪制一個柱狀圖了。

首先,回到 <code>BarGraphViewController</code>,你需要一對常量屬性。把下面這段添加到其他屬性之前:

let BarWidth = 0.25

let BarInitialX = 0.25

你還需要一個幫助函數去計算最高的率值。把下面這段添加到 <code>updateLabels()</code>之後:

func highestRateValue() -&gt; Double {

var maxRate = DBL_MIN

for rate in rates {

maxRate = max(maxRate, rate.maxRate().doubleValue)

return maxRate

接着,把下面的方法添加到 <code>highestRateValue()</code> 之後:

configureAxes()

func configureAxes() {

是不是看上去很眼熟?是的,這些和之前的結構完全一樣。

下面這行添加到 <code>configureHostView()</code> 裡:

因為你不需要捏合縮放,是以你應該再次把它禁用。

接着,把下面那麼多行代碼添加到 <code>configureGraph()</code> 裡:

29

30

31

32

33

34

// 1 - Create the graph

graph.plotAreaFrame?.masksToBorder = false

// 2 - Configure the graph

graph.applyTheme(CPTTheme(named: kCPTPlainWhiteTheme))

graph.fill = CPTFill(color: CPTColor.clearColor())

graph.paddingBottom = 30.0

graph.paddingLeft = 30.0

// 3 - Set up styles

let titleStyle = CPTMutableTextStyle()

titleStyle.color = CPTColor.blackColor()

titleStyle.fontName = "HelveticaNeue-Bold"

titleStyle.fontSize = 16.0

titleStyle.textAlignment = .Center

graph.titleTextStyle = titleStyle

let title = "\(base.name) exchange rates\n\(rates.first!.date) - \(rates.last!.date)"

graph.title = title

graph.titlePlotAreaFrameAnchor = .Top

graph.titleDisplacement = CGPointMake(0.0, -16.0)

// 4 - Set up plot space

let xMin = 0.0

let xMax = Double(rates.count)

let yMin = 0.0

let yMax = 1.4 * highestRateValue()

guard let plotSpace = graph.defaultPlotSpace as? CPTXYPlotSpace else { return }

plotSpace.xRange = CPTPlotRange(locationDecimal: CPTDecimalFromDouble(xMin), lengthDecimal: CPTDecimalFromDouble(xMax - xMin))

plotSpace.yRange = CPTPlotRange(locationDecimal: CPTDecimalFromDouble(yMin), lengthDecimal: CPTDecimalFromDouble(yMax - yMin))

下面是這段代碼邏輯的拆解:

首先,執行個體化一個 <code>CPTXYGraph</code>,實際上就是一個柱狀圖,并将它關聯到 <code>hostView</code>。

然後聲明一個 簡約的白色 預設主題并為了展示 XY 軸去設定左側和下方的内邊距。

接着設定文本樣式,圖表标題以及标題位置。

最後,配置 <code>CPTXYPlotSpace</code>,它負責将裝置的坐标系映射到圖表的坐标系。針對這個圖表,你正在繪制三個使用了相同坐标系的匯率。然而,也有可能每個條形圖的坐标系都是 分離 的。你還要在坐标系中假定一個最大最小值匯率範圍。在後面的教程中,你将學習到怎麼樣在不提前設定範圍的情況下自動調節空間大小。

既然已經建立好圖表了,那是時候增加一些繪制方法進去了!把下面的代碼添加到 <code>configureChart()</code>裡:

// 1 - Set up the three plots

plot1 = CPTBarPlot()

plot1.fill = CPTFill(color: CPTColor(componentRed:0.92, green:0.28, blue:0.25, alpha:1.00))

plot2 = CPTBarPlot()

plot2.fill = CPTFill(color: CPTColor(componentRed:0.06, green:0.80, blue:0.48, alpha:1.00))

plot3 = CPTBarPlot()

plot3.fill = CPTFill(color: CPTColor(componentRed:0.22, green:0.33, blue:0.49, alpha:1.00))

// 2 - Set up line style

let barLineStyle = CPTMutableLineStyle()

barLineStyle.lineColor = CPTColor.lightGrayColor()

barLineStyle.lineWidth = 0.5

// 3 - Add plots to graph

var barX = BarInitialX

let plots = [plot1, plot2, plot3]

for plot: CPTBarPlot in plots {

plot.dataSource = self

plot.delegate = self

plot.barWidth = BarWidth

plot.barOffset = barX

plot.lineStyle = barLineStyle

graph.addPlot(plot, toPlotSpace: graph.defaultPlotSpace)

barX += BarWidth

接着來看看上面的代碼幹了什麼:

執行個體化每個條形圖并設定它們的填充色。

執行個體化一個代表每個條形圖的外部邊框的 <code>CPTMutableLineStyle</code> 執行個體。

給每個條形圖提供“共同配置”。該配置包括設定資料源和代理,寬度和每個條形圖在坐标系中的相對位置(左右)以及線條樣式,最後,添加這個坐标系到圖表當中。

雖然還不可以看到柱狀圖展示出來,但通過建構 app 可以去驗證目前為止是否所有代碼都可以正确編譯通過。

為了确切看到柱狀圖展示資料出來,需要去實作提供圖表所需資料的代理方法。

用下面這行替換掉 <code>numberOfRecordsForPlot(:_)</code>:

return UInt(rates.count ?? 0)

該方法傳回了應該展示的記錄的總數。

下面這段替換掉 <code>numberForPlot(_:field:recordIndex:)</code>:

if fieldEnum == UInt(CPTBarPlotField.BarTip.rawValue) {

if plot == plot1 {

return 1.0

if plot == plot2 {

return rates[Int(idx)].rates[symbols[0].name]!.floatValue

if plot == plot3 {

return rates[Int(idx)].rates[symbols[1].name]!.floatValue

return idx

<code>CPTBarPlotField.BarTip</code> 的值表明了柱狀圖的相對大小。在你需要取回資料的時候可以使用保留屬性計算出匯率,<code>recordIndex</code> 對應了利息率的位置。

建構并運作,你應該可以看到和下面這張圖一樣的情況:

iOS 開源圖形庫 Core Plot 使用教程

已經快完成了!但請注意還沒有任何東西指明每個坐标軸是代表什麼意思。

要解決這個問題,把下面這段添加進 <code>configureAxes()</code>:

35

36

37

38

39

40

41

42

// 1 - Configure styles

let axisLineStyle = CPTMutableLineStyle()

axisLineStyle.lineWidth = 2.0

axisLineStyle.lineColor = CPTColor.blackColor()

// 2 - Get the graph's axis set

guard let axisSet = hostView.hostedGraph?.axisSet as? CPTXYAxisSet else { return }

// 3 - Configure the x-axis

if let xAxis = axisSet.xAxis {

xAxis.labelingPolicy = .None

xAxis.majorIntervalLength = 1

xAxis.axisLineStyle = axisLineStyle

var majorTickLocations = Set&lt;nsnumber&gt;()

var axisLabels = Set&lt;cptaxislabel&gt;()

for (idx, rate) in rates.enumerate() {

majorTickLocations.insert(idx)

let label = CPTAxisLabel(text: "\(rate.date)", textStyle: CPTTextStyle())

label.tickLocation = idx

label.offset = 5.0

label.alignment = .Left

axisLabels.insert(label)

xAxis.majorTickLocations = majorTickLocations

xAxis.axisLabels = axisLabels

// 4 - Configure the y-axis

if let yAxis = axisSet.yAxis {

yAxis.labelingPolicy = .FixedInterval

yAxis.labelOffset = -10.0

yAxis.minorTicksPerInterval = 3

yAxis.majorTickLength = 30

let majorTickLineStyle = CPTMutableLineStyle()

majorTickLineStyle.lineColor = CPTColor.blackColor().colorWithAlphaComponent(0.1)

yAxis.majorTickLineStyle = majorTickLineStyle

yAxis.minorTickLength = 20

let minorTickLineStyle = CPTMutableLineStyle()

minorTickLineStyle.lineColor = CPTColor.blackColor().colorWithAlphaComponent(0.05)

yAxis.minorTickLineStyle = minorTickLineStyle

yAxis.axisLineStyle = axisLineStyle

}&lt;/cptaxislabel&gt;&lt;/nsnumber&gt;

簡單地說,上面的代碼首先為軸線和标題定義了樣式,然後,為圖表添加坐标軸的設定并配置好 x 軸和 y 軸的一些屬性。

建構并運作就可以看到這些改動的結果了。

iOS 開源圖形庫 Core Plot 使用教程

更棒了對吧?唯一的缺陷在于這個坐标軸太簡單了,沒辦法從這兒得到一個準确的匯率展示。

你可以修複這個問題以便當使用者點按在一個單獨的柱狀圖時,這個 app 可以展示這個圖表示的匯率。為了實作它,需要增加一個新的屬性:

var priceAnnotation: CPTPlotSpaceAnnotation?

然後把下面的代碼添加到 <code>barPlot(_:barWasSelectedAtRecordIndex:)</code>:

43

// 1 - Is the plot hidden?

if plot.hidden == true {

return

// 2 - Create style, if necessary

let style = CPTMutableTextStyle()

style.fontSize = 12.0

style.fontName = "HelveticaNeue-Bold"

// 3 - Create annotation

guard let price = numberForPlot(plot,

field: UInt(CPTBarPlotField.BarTip.rawValue),

recordIndex: idx) as? CGFloat else { return }

priceAnnotation?.annotationHostLayer?.removeAnnotation(priceAnnotation)

priceAnnotation = CPTPlotSpaceAnnotation(plotSpace: plot.plotSpace!, anchorPlotPoint: [0,0])

// 4 - Create number formatter

let formatter = NSNumberFormatter()

formatter.maximumFractionDigits = 2

// 5 - Create text layer for annotation

let priceValue = formatter.stringFromNumber(price)!

let textLayer = CPTTextLayer(text: priceValue, style: style)

priceAnnotation!.contentLayer = textLayer

// 6 - Get plot index

var plotIndex: Int = 0

plotIndex = 0

else if plot == plot2 {

plotIndex = 1

else if plot == plot3 {

plotIndex = 2

// 7 - Get the anchor point for annotation

let x = CGFloat(idx) + CGFloat(BarInitialX) + (CGFloat(plotIndex) * CGFloat(BarWidth))

let y = CGFloat(price) + 0.05

priceAnnotation!.anchorPlotPoint = [x, y]

// 8 - Add the annotation

guard let plotArea = plot.graph?.plotAreaFrame?.plotArea else { return }

plotArea.addAnnotation(priceAnnotation)

這裡需要一些解釋:

不要給一個隐藏的柱狀圖展示注解,而當圖沒有設定隐藏屬性的時候,在把切換開關整合到圖表之後,你就将實作它了。

這裡還要為你的注解建立一個文本樣式。

得到指定柱狀圖的匯率,然後如果它不存在一個注解對象,就建立一個。

如果沒有數值格式化的方法還需要建立一個,因為在匯率展示的時候需要先格式化它。

建立一個使用這個格式化匯率的文本層,并将注解的内容層設定到這個新的文本層上。

擷取你将展示的注解需要放置的柱狀圖索引。

基于這個索引計算注解的位置,并給使用這個計算位置注解設定 <code>anchorPlotPoint</code> 的值。

最後,将注解添加到圖表上。

建構并運作。每次當你點按圖表中的一個柱體時,該柱體所表示的值就應該正好在其上方彈出來。

棒極了! :]

iOS 開源圖形庫 Core Plot 使用教程

這個柱狀圖看起來很棒,但螢幕最上方的切換開關并沒有起什麼作用,是時候改動它們了。

首先,需要添加一個幫助方法,把下面這段添加到 <code>switch3Changed(_:)</code> 之後:

func hideAnnotation(graph: CPTGraph) {

guard let plotArea = graph.plotAreaFrame?.plotArea,

priceAnnotation = priceAnnotation else {

plotArea.removeAnnotation(priceAnnotation)

self.priceAnnotation = nil

這段代碼首先簡單地移除了一個如果存在的注解。

下一步,你希望使用者通過切換開關展示一個給定的貨币匯率柱狀圖。

要做到這個功能,用下面這段替換到 <code>switch1Changed(_:)</code>,<code>switch2Changed(_:)</code> 和 <code>switch3Changed(_:)</code> 的實作。

@IBAction func switch1Changed(sender: UISwitch) {

let on = sender.on

if !on {

hideAnnotation(plot1.graph!)

plot1.hidden = !on

@IBAction func switch2Changed(sender: UISwitch) {

hideAnnotation(plot2.graph!)

plot2.hidden = !on

@IBAction func switch3Changed(sender: UISwitch) {

hideAnnotation(plot3.graph!)

plot3.hidden = !on

這個邏輯相當簡單。如果開關設定了關閉,相關的圖和其可見的注解就将被隐藏,而如果設定為開啟,則圖就會被設定為可見。

建構并運作。現在你可以在圖表中随意切換每個柱狀圖的展示了。教程至此已經完成了很不錯的工作!

iOS 開源圖形庫 Core Plot 使用教程

哇哦,相當有趣!這個教程重點介紹了 Core Plot 的強大功能并希望提示了你該怎麼在你自己的 apps 裡使用它。

還有,如果你對這個教程有任何的問題或者評論,歡迎加入下面的論壇進行讨論。

祝你有個快樂的繪圖過程!

<b></b>

<b>原文釋出時間為:2016年07月20日</b>

<b>本文來自雲栖社群合作夥伴掘金,了解相關資訊可以關注掘金網站。</b>