必要環境
今回の記事における筆者の環境は下記の通りです。実際は、これより新しくても動作すると思われます。
- Xcode Version 7.2(7C68)
- Mac OS X Yosemite 10.10.5
- Xuni 2015J v3
まずは動かしてみよう
Xuniの概要やインストールについては、第1回で説明していますので省略します。早速サンプルプログラムを動かしてみましょう。
サンプルプログラムはAndroidと同様の場所に保存されています。
~/Documents/XuniJp/iOS/Samples
Androidでも試したFlexGridのサンプルを見ていきます。
Xcodeからプロジェクトを開く
iOS版は、従来からあるObjective-Cと比較的新しいSwiftの2種類の言語を選択できます。今回は新しいSwiftを使用します。次のサンプルプロジェクトをXcodeにて開きます。
~/Documents/XuniJp/iOS/Samples/Swift/FlexGrid101
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_001_s.gif)
アプリを実行する
Runボタンをクリックして実行します。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_002_s.gif)
シミュレーターが立ち上がり、アプリが起動します。「列の定義」をタッチしましょう。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_003_s.gif)
Android同様スワイプでスクロール、タップで選択が出来ます。ダブルタップで編集は「セル内容の編集」の画面で出来ます。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_004_s.gif)
アプリの実装を見る
iOSのアプリの画面はStoryBoardで組み立てます。各画面の遷移は線をつなげて関連を表します。今回は最初のMenuから各画面に遷移するので、Menuからの各画面への線が張り巡らされています。
![StoryBoard](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_005_s.gif)
![StoryBoardの詳細](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_005a_s.gif)
実装の詳細を見てみると、画面名ごとにControllerがあります。例えば先の「列の定義」であれば、「ColumnDefinitionController.swift」になります。どのような実装になっているか見てみましょう。
class ColumnDefinitionController: UIViewController { var _flex = FlexGrid() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. _flex.autoGenerateColumns = false //(1) let c1 = FlexColumn() c1.binding = "customerID" c1.header = NSLocalizedString("ID", comment: "") c1.width = 100 let c2 = FlexColumn() c2.binding = "firstName" c2.header = NSLocalizedString("First name", comment: "") let c3 = FlexColumn() c3.header = NSLocalizedString("Last name", comment: "") c3.binding = "lastName" let c4 = FlexColumn() c4.binding = "orderTotal" c4.header = NSLocalizedString("Total orders", comment: "") c4.format = "N1" _flex.columns.addObject(c1) _flex.columns.addObject(c2) _flex.columns.addObject(c3) _flex.columns.addObject(c4) //(2) _flex.itemsSource = CustomerData.getCustomerData(100) //(3) _flex.isReadOnly = true //(4) self.starSizing(_flex) //(5) self.view.addSubview(_flex) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() _flex.frame = CGRectMake(0, 65, self.view.bounds.size.width, self.view.bounds.size.height - 65) _flex.setNeedsDisplay() } func starSizing(g: FlexGrid){ for var i : UInt = 0; i < g.columns.count; i++ { var c = FlexColumn() c = g.columns.objectAtIndex(i) as! FlexColumn c.widthType = FlexColumnWidth.Star c.width = (i == 0) ? 3 : (i == 3) ? 3 : 4 } } }
- FlexGridの各カラムを設定する。
- itemSourceに対してFlexGridに表示するデータソースを設定する。
- 読み取り専用にする
- スターサイズ機能を使用して列のサイズを横スクロールしないように調整する
- ビューにFlexGridを追加する
XuniのAndroid版と見比べてどうでしょうか? JavaとSwiftの文法の細かい違いはありますが、FlexGrid自体の使用方法はそれほど変わらないと思います。
クラウドにデータを用意する
次にクラウドと通信してデータを取得する部分を作成します。利用するデータは「Azure Web Apps」に用意します。データの準備やクラウドへの配置、REST API作成の手順は、第2回「クラウド上のデータをグリッドやグラフで表示してみよう」で作成したAndroidアプリと同じなので、第2回を参照してください。
FlexGridからREST APIを呼び出す
データをREST APIから取得する方法も、Androidアプリ同様に、Azure Mobile AppsのSDKを利用します。「MicrosoftAzureMobile.framework」をプロジェクトに組み込みます。サンプルコードでは、「ColumnDefinitionController.swift」に組み込んでいます。以降説明する実装はすべて組み込み済みです。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_006.gif)
次に、前述の「ColumnDefinitionController.swift」の(2)でサンプルデータを作成していた箇所を、次のように書き換えます。
//(2) itemsSourceにAzureから取得したJSONを格納するように変更する let client = MSClient(applicationURLString:"https://62ad1595-0ee0-4-231-b9ee.azurewebsites.net") client.invokeAPI("population", body: nil, HTTPMethod: "GET", parameters:nil, headers: nil) { (data, response, error) -> Void in let newArray = data!["populations"] as? NSMutableArray let populationArray = NSMutableArray() for item in newArray! { let dicItem = item as! NSDictionary let population = PopulationData() population.year = dicItem["year"] as! Int population.under14 = dicItem["under14"] as! Int population.between15to64 = dicItem["between15to64"] as! Int population.over65 = dicItem["over65"] as! Int population.sum = dicItem["sum"] as! Int populationArray.addObject(population) } self._flex.itemsSource = populationArray }
"https://62ad1595-0ee0-4-231-b9ee.azurewebsites.net"は、Azure Web AppsのURLで、第2回で取得方法を説明しています。<62ad1595-0ee0-4-231-b9ee>の部分はユーザーごとに異なりますので、皆様の環境に合わせて書き換えて下さい。
FlexGridの機能を見る
つづいて、FlexGridの機能を解説します。
フィルタ
フィルタについては「フィルタ処理」をご確認ください。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_007_s.gif)
さらに「フィルタ処理」を選択するとフィルタ画面が表示されます。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_008_s.gif)
フィルタ画面にて「Noah」と入力し、「値と同じ」を選び「フィルタ処理」をタッチします。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_009_s.gif)
すると、「Noah」と一致するセルのみが表示されます。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_010_s.gif)
実装の詳細は「FilterController.swift」及び「FilterFormController.swift」を参照して下さい。
ソート
再び「列の定義」を見ていただき、カラムをタップするごとに昇順・降順でソートが可能です。Androidと同様にデフォルトで有効になっており特に実装は不要です。年次をタップして降順にした画面がこちらです。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_011_s.gif)
グラフを表示する
次にグラフで表示してみましょう。
FlexChartを追加する
グラフを表示するために、「XuniChartCoreKit.framework」と「XuniFlexChartKit.framework」をプロジェクトに追加します。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_012.gif)
グラフ画面を表示するボタンを追加する
Androidと考え方は同じです。「ColumnDefinitionController.swift」にグラフ表示のボタンを追加し、「PopulationGraphController」の画面を表示できるようにします。画面を表示する際に、人口のデータをパラメーターとして渡します。
override func viewDidLoad() { // ... 中略 ... //(6) グラフ表示ボタンを追加 _graphButton = UIButton(type: UIButtonType.System) _graphButton.setTitle("グラフ表示", forState: UIControlState.Normal) _graphButton.addTarget(self, action: "graphButtonClicked", forControlEvents: UIControlEvents.TouchUpInside) self.view.addSubview(_graphButton) // グラフ表示ボタンが押された時の処理 func graphButtonClicked(){ self.performSegueWithIdentifier("GraphFormSegue", sender: self) }
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_013_s.gif)
グラフ表示画面を実装する
Androidのときと少し違うのは、前の画面から受け取るパラメーターをセットするのは前の画面ということです。具体的には、ColumnDefinitionControllerのprepareForSegueにて、PopulationGraphControllerにitemsSourceをセットします。
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?{ if segue.identifier == "GraphFormSegue" { let populationGraphController = segue.destinationViewController a PopulationGraphController populationGraphController._chart.itemsSource self._flex.itemsSource } }
棒グラフが表示されます。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_014_s.gif)
Androidと同様に、このままでは見づらいので折れ線グラフにしてみましょう。グラフの種類はPopulationGraphControllerに次のようにセットするだけで簡単に切り替えられます。
_chart.chartType = XuniChartType.Line
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_015_s.gif)
積み上げ面グラフにしてみます。設定は次の通りです。
_chart.chartType = XuniChartType.Area _chart.stacking = XuniStacking.Stacked
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_016_s.gif)
軸に説明を追加する
縦軸・横軸の単位を設定します。
_chart.axisX.title = "年次" _chart.axisY.title = "人口(単位:1000人)"
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_017_s.gif)
横画面も綺麗に表示されます。以下はiPadで表示させてみたものです。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_018a_s.gif)
ズームを有効にする
ピンチイン・ピンチアウトによるズームを有効にする場合、これもAndroidとほぼ同じコードで実現できます。
_chart.zoomMode = XuniZoomMode.XY
iPadでズームした場合、以下のような表示になります。
![](http://cz-cdn.shoeisha.jp/static/images/article/9344/9344_019a_s.gif)
まとめ
Xuniで、iOSもAndroid同様にデータを表示することができました。iOS版も「Xuni for iOS のユーザーガイド」及び「Xuni for iOS のAPI リファレンス」が参考になりますが、Objective-Cで記述されているため、Swiftは多少読み替えが必要です。
そのときは本記事を参照していただくか、サンプルソースにはObjective-CとSwift版が同梱されていますので、両者を見比べるとヒントが得られるかもしれません。
Xuniは、AndroidとiOSで実装方法はほぼ同じで、画面もほぼ同様に表示されます。グリッドとグラフがひとつで実現でき、使い勝手も良いコンポーネントですので、ぜひ皆様お試し下さい。