• 検索結果がありません。

iOSにおける描画と印刷のガイド (TP )

N/A
N/A
Protected

Academic year: 2021

シェア "iOSにおける描画と印刷のガイド (TP )"

Copied!
96
0
0

読み込み中.... (全文を見る)

全文

(1)

iOSにおける

(2)

目次

iOSでの描画と印刷

7 初めに 8 カスタムUIビューを導入すれば描画の自由度が高まる 8 アプリケーションはオフスクリーンビットマップやPDFに描画できる 10 印刷に関する一連のオプション 10 高解像度画面対応への変更は容易 11 関連項目 11

iOSにおける描画の考え方

12 UIKitのグラフィックスシステム 12 ビューの描画サイクル 13 iOSにおける座標系と描画 14 ポイントとピクセル 16 グラフィックスコンテキストを取得する 18 色と色空間 20 QuartzとUIKitを使用した描画 20 グラフィックスコンテキストの設定 21 パスの作成と描画 23 パターン、グラデーション、陰影の作成 24 座標系のカスタマイズ 24 Core Animation効果の適用 27 レイヤについて 28 アニメーションについて 28 Core Animationレイヤの倍率の考慮 29

ベジエパスを使用した図形の描画

30 ペジエパスの基礎 30 パスへの直線と多角形の追加 31 パスへの弧の追加 32 パスへの曲線の追加 34 楕円パスと矩形パスの作成 35 Core Graphicsの関数を使用したパスの変更 35 ペジエパスオブジェクトのコンテンツのレンダリング 37 パス上でのヒット検出 38

(3)

画像の描画と生成

40 画像の描画 40 ビットマップグラフィックスコンテキストを使って新しい画像を生成 41

PDFコンテンツの生成

45 PDFコンテキストの作成と設定 45 PDFページの描画 48 PDFコンテンツ内でのリンクの作成 50

プリント

52 簡単かつ直感的に設計されたiOSでの印刷 52 印刷ユーザインターフェイス 52 iOSでの印刷の仕組み 56 UIKitの印刷API 58 印刷サポートの概要 58 印刷のワークフロー 60 プリンタ対応のコンテンツの印刷 62 印刷フォーマッタやページレンダラの利用 64 印刷ジョブのレイアウトプロパティの設定 64 印刷フォーマッタの使用 66 ページレンダラの使い方 70 アプリケーションコンテンツの印刷テスト 74 一般的な印刷タスク 75 印刷の可否のテスト 75 印刷ジョブ情報の指定 76 用紙サイズ、向き、印刷枚数の指定 77 印刷機能をユーザインターフェイスに統合 78 印刷ジョブの完了とエラーへの応答 81

描画パフォーマンスの改善

82

ビューにおける高解像度画面のサポート

84 高解像度画面のサポートのためのチェックリスト 84 無償で手に入る描画機能の向上 85 画像リソースファイルの更新 85 アプリケーションへの画像の読み込み 86 Image Viewを使用した複数の画像の表示 87 アプリケーションのアイコンと起動画像の更新 87 OpenGL ESまたはGLKitを使った高解像度コンテンツの描画 87 目次

(4)

画像のロード

90 画像のためのシステムサポート 91 UIKitの画像クラスと関数 91 その他の画像関連フレームワーク 92 サポートされる画像形式 93 画像品質の維持 93

書類の改訂履歴

95 目次

(5)

図、表、リスト

iOSでの描画と印刷

7 図 I-1 カスタムビューには、標準ビューと組み合わせる、オフスクリーン描画する、などと いった使い方がある。 7

iOSにおける描画の考え方

12 図 1-1 描画座標系、ビュー座標系、ハードウェア座標系の関係 14 図 1-2 iOSのデフォルト座標系 15 図 1-3 1ポイント幅の線を、その中心のポイント値が整数であるように描画した様子 17 図 1-4 1ポイント幅の線の描画状態:標準ディスプレイとRetinaディスプレイ 18 図 1-5 Core GraphicsおよびUIKitでレンダリングした弧の向き 26 表 1-1 グラフィックスの状態を変更するCore Graphics関数 22

ベジエパスを使用した図形の描画

30 図 2-1 UIBezierPathクラスのメソッドを利用して描画した図形 32 図 2-2 デフォルトの座標系での弧 33 図 2-3 パス内の曲線セグメント 34 リスト 2-1 五角形の作成 31 リスト 2-2 弧パスの新規作成 33 リスト 2-3 新規のCGPathRefをUIBezierPathオブジェクトに割り当てる 35 リスト 2-4 Core Graphics呼び出しとUIBezierPath呼び出しの併用 36

リスト 2-5 ビューにパスを描画する 37 リスト 2-6 パスオブジェクトに対する点のテスト 39

画像の描画と生成

40 リスト 3-1 縮小画像をビットマップコンテキストに描画し、その結果の画像を取得する 42 リスト 3-2 Core Graphics関数を使用したビットマップコンテキストへの描画 43

PDFコンテンツの生成

45 図 4-1 リンク先とジャンプ元の作成 51 リスト 4-1 PDFファイルの新規作成 46 リスト 4-2 ページ単位のコンテンツの描画 49

プリント

52 図 5-1 印刷に使われるシステム項目アクションボタン 53

(6)

図 5-2 プリンタオプションのPopoverビュー(iPad) 53 図 5-3 プリンタオプションページ(iPhone) 54 図 5-4 Print Center 55 図 5-5 Print Center:印刷ジョブの詳細 56 図 5-6 印刷のアーキテクチャ 57 図 5-7 UIKitの印刷オブジェクトの関係 58 図 5-8 複数ページの印刷ジョブのレイアウト 66 表 5-1 アプリケーションコンテンツの印刷方法の決定 59 リスト 5-1 ページ範囲の選択が可能な単一のPDFドキュメント 63 リスト 5-2 HTMLドキュメント(ヘッダ情報なし)の印刷 68 リスト 5-3 Web Viewのコンテンツの印刷 69 リスト 5-4 ページのヘッダとフッタの描画 72 リスト 5-5 印刷の可否に基づいて印刷ボタンを有効または無効にする 75 リスト 5-6 UIPrintInfoオブジェクトのプロパティを設定して、それをprintInfoプロパティに割 り当てる 76 リスト 5-7 画像の寸法に合うように印刷の向きを設定する 77 リスト 5-8 printInteractionController:choosePaper:メソッドの実装 78 リスト 5-9 現在のデバイスタイプに応じて印刷オプションを表示する 79 リスト 5-10 完了ハンドラブロックの実装 81

描画パフォーマンスの改善

82 表 A-1 描画パフォーマンス改善のヒント 82

ビューにおける高解像度画面のサポート

84 リスト B-1 レンダバッファのストレージの初期化と実際の寸法の取得 88

画像のロード

90 表 C-1 画像使用のシナリオ 90 表 C-2 サポートされる画像形式 93 図、表、リスト

(7)

この資料では関連する3つの話題を扱います。 ● カスタムUIビューの描画。標準的なUI要素には容易に描画できないものでも、カスタムUIビュー であれば描画できることがあります。たとえば、描画プログラムがユーザの描画用に使う、アー ケードゲームがスプライトを描画する、などといったことが可能です。 ● オフスクリーンビットマップやPDFコンテンツに描画。画像を後で表示する、ファイルにエクス ポートする、AirPrint対応プリンタに印刷するなどの目的で、オフスクリーン描画の機能を活用す れば、ユーザの作業を妨げることがありません。 ● アプリケーションのAirPrint対応。iOS印刷システムを活用すれば、さまざまなページに合わせて 出力できます。 図 I-1 カスタムビューには、標準ビューと組み合わせる、オフスクリーン描画する、などといった使い 方がある。

iOSでの描画と印刷

(8)

初めに

iOSネイティブのグラフィックスシステムは、UIKit、Core Graphics、Core Animationという3つの重要な 技術を組み合わせたものです。UIKitは、ビューと、ビューに対する若干の高レベル描画機能を提供し ます。Core GraphicsにはUIKitのビューに対する(低レベルの)描画機能があります。さらに、Core Animationを利用すれば、UIKitのビューに対する座標変換やアニメーション表示が可能になります。 Core Animationはビューの合成も行います。

カスタムUIビューを導入すれば描画の自由度が高まる

この資料では、ネイティブの描画技術により、カスタムUIビューに描画する方法を説明します。Core GraphicsフレームワークやUIKitフレームワークを含むネイティブの描画テクノロジーは、2Dの描画を サポートしています。 カスタムUIビューの導入を検討する前に、それが本当に必要かどうか考えてみてください。ネイティ ブ描画は、より複雑な2Dレイアウトを要する場合に向いています。しかし、カスタムビューはプロ セッサに対する負荷も大きいので、この技術により描画する量は控えめにしなければなりません。 iOSアプリケーションがオンスクリーン描画に利用できる代替手段には、次のようなものがあります。 ● 標準(組み込み)ビューを使う。標準ビューには、リスト、コレクション、警告、画像、進捗 バー、テーブルなど、よく使われるUIプリミティブを描画できます。描画のためにわざわざコー ドを記述する必要はありません。一般的なiOSアプリケーションと同じ使い勝手が得られるばかり でなく、開発作業が少なくて済むという利点もあります。組み込みビューが目的に合っているの であれば、『View Programming Guide for iOS 』を参照してください。

Core Animationレイヤを使う。Core Animationを利用すれば、複雑な階層2Dビューを作成でき、ア

ニメーション表示や座標変換の機能も使えます。アニメーションつきの標準ビューとしても、 ビューを複雑に組み合わせて幻想的な効果を生み出す目的にも優れています。以下に説明するよ うに、カスタムビューと組み合わせることも可能です。Core Animationについて詳しくは、『Core Animation Overview 』を参照してください。GLKitのビューやカスタムビューでOpenGL ESを使う。OpenGL ESフレームワークはオープン標準の グラフィックスライブラリ群で、主としてゲーム開発や、高フレームレートの表示を要するアプ リケーション(仮想プロトタイプ、機械/建設設計など)を想定しています。OpenGL ES 2.0および OpenGL ES v1.1の仕様に準拠しています。OpenGLを用いた描画について詳しくは、『OpenGL ES Programming Guide for iOS 』を参照してください。

● ウェブコンテンツを使う。UIWebViewクラスには、iOSアプリケーション上に、ウェブベースの

ユーザインターフェイスを表示する機能があります。ウェブビューにウェブコンテンツを表示す る方法について詳しくは、『Using UIWebView to display select document types 』および『UIWebView Class Reference 』を参照してください。

(9)

作成するアプリケーションのタイプに応じて、カスタム描画コードをほとんど、あるいはまったく使 用しないで済ませることができます。没入型のアプリケーションでは通常、カスタム描画コードを惜 しみなく使用しますが、ユーティリティ型アプリケーションや生産性型アプリケーションであれば、 標準のビューやコントロールを使用してコンテンツを表示できることが少なくありません。 カスタム描画コードは、表示するコンテンツを動的に変化させる必要のある場合に限定するべきで す。たとえば、描画アプリケーションであれば、カスタム描画コードを使用してユーザの描画コマン ドを追跡する必要がありますし、アーケードゲームであれば、常に変化するゲームの状況を反映する ため絶えず画面を更新することになります。これらの状況では、適切な描画テクノロジーを選択し、 カスタムビュークラスを作成してイベントを処理し、表示を適切に更新する必要があります。 一方、アプリケーションのインターフェイスの大半が固定されている場合、あらかじめインターフェ イスを1つ以上の画像ファイルにレンダリングしておき、UIImageViewクラスを使用して、それらの 画像を実行時に表示することができます。インターフェイスを構築する際に、必要に応じてほかのコ ンテンツとImage View群を重ねることができます。UILabelクラスを使用して、設定変更可能なテキ

ストを表示し、ボタンなどのコントロールを追加して対話機能を提供することも可能です。たとえば 電子版のボードゲームは、独自の描画コードをほとんど記述せずに実装できることも少なくありませ ん。 カスタムビューは一般に、プロセッサに対する負荷が大きい(GPUの支援を受けにくい)傾向がある ので、やりたいことが標準ビューで実現できるのであれば、ぜひそうしてください。さらに、カスタ ムビューはできるだけ小規模に抑え、他の方法で描画できないものだけに限定し、それ以外は標準 ビューを利用するとよいでしょう。標準UI要素とカスタム描画を組み合わせる必要があれば、Core Animationレイヤを利用して、標準ビュー上にカスタムビューを重ね合わせ(スーパーインポーズ)、 できるだけ描画処理の負荷を抑えてください。

描画の基礎を支える重要な概念

UIKitとCore Graphicsを利用してコンテンツを描画する場合は、ビューの描画サイクルのほかに、いく つかの概念に精通していなければなりません。 ● drawRect:メソッドでは、UIKitはディスプレイにレンダリングするためのグラフィックスコンテ キストを作成します。このグラフィックスコンテキストには、描画システムが描画コマンドを実 行するために必要な情報(塗りつぶし色、描画色、フォント、クリッピング領域、線の幅などの 属性を含む)が含まれています。また、ビットマップ画像やPDFコンテンツの描画用にカスタム グラフィックスコンテキストを作成して描画することもできます。 ● UIKitは、ビューの左上角を描画の原点とするデフォルト座標系を持っています。正の座標値は、 左上角の原点から下および右の方向に伸びます。現在の変換行列(ビューの座標空間をデバイス の画面にマップする)を修正することによって、サイズ、向き、および基盤となるビューやウイ ンドウを基準にしたデフォルト座標系の位置を変更できます。 初めに

(10)

iOSでは、論理座標空間(ポイント単位で距離を表す)は、デバイスの座標空間(単位はピクセ

ル)と同じではありません。精度を高めるために、ポイント数は浮動小数点値で表します。

関連する章: “iOSにおける描画の考え方” (12 ページ)

UIKit、Core Graphics、Core Animationが提供する多数の描画ツール

UIKitとCore Graphicsには、グラフィックスコンテキスト、ベジェパス、画像、ビットマップ、透過レ イヤ、色、フォント、PDFコンテンツ、描画矩形とクリッピング領域など、多数の補足的なグラフィッ クス機能が揃っています。さらに、Core Graphicsには線の属性、色空間、パターン色、グラデーショ ン、影、および画像マスクに関連する関数があります。Core Animationフレームワークを利用すると、 ほかのテクノロジーで作成したコンテンツを操作したり表示したりして、滑らかなアニメーションを 作成できます。 関連する章: “iOSにおける描画の考え方” (12 ページ)、“ベジエパスを使用した図形の描 画” (30 ページ)、“画像の描画と生成” (40 ページ)、“PDFコンテンツの生成” (45 ペー ジ)

アプリケーションはオフスクリーンビットマップやPDFに描画できる

オフスクリーン描画の機能もさまざまな状況で役立てることができます。 ● オフスクリーンビットマップコンテキストは、写真を縮小してアップロードする、ストレージ目 的でコンテンツを画像ファイルの形にレンダリングする、Core Graphicsを使って複雑な画像を生 成して表示する、などのためによく使われます。 ● 一方、オフスクリーンPDFコンテキストは、印刷目的で、ユーザが生成したコンテンツを描画す る際によく使われます。 生成したオフスクリーンコンテキストを描画する処理は、カスタムビューのdrawRect:メソッドに記 述する描画処理とほとんど同じです。 関連する章: “画像の描画と生成” (40 ページ)、“PDFコンテンツの生成” (45 ページ)

印刷に関する一連のオプション

iOS 4.2以降、AirPrintを利用すれば、対応プリンタに無線で印刷できるようになりました。印刷ジョブ を組み立てる際に、アプリケーションは次の3つの方法でUIKitに印刷対象コンテンツを提供できます。 初めに

(11)

● 直接印刷可能な1つまたは複数のオブジェクトをフレームワークに渡す。この場合、アプリケー

ションの関与は最小限しか必要としません。画像データやPDFコンテンツを保持または参照する ものとして、NSData、NSURL、UIImage、ALAssetの各クラスのインスタンスがあります。

● 印刷ジョブに印刷フォーマッタを割り当てる。印刷フォーマッタは、特定のタイプのコンテンツ (プレーンテキスト、HTMLなど)を複数のページにレイアウトできるオブジェクトです。 ● 印刷ジョブにページレンダラを割り当てる。通常、ページレンダラは印刷するコンテンツの一部 または全部を描画するUIPrintPageRendererのカスタムサブクラスのインスタンスです。ページ レンダラは、1つ以上の印刷フォーマッタを使用して、描画に利用したり、印刷可能なコンテン ツを整形します。 関連する章: “プリント” (52 ページ)

高解像度画面対応への変更は容易

iOSデバイスのなかには、高解像度画面を備えているものがあるため、アプリケーションは高解像度 画面のデバイスと低解像度画面のデバイスの両方で動作するように準備する必要があります。さまざ まな解像度に対応するために必要な作業のほとんどはiOSが処理しますが、アプリケーション側で行 うべき作業もいくつかあります。たとえば、特別に指定された高解像度の画像を提供したり、現在の 倍率を反映するためにレイヤ関連や画像関連のコードを修正したりする作業などがあります。 関連する付録: “ビューにおける高解像度画面のサポート” (84 ページ)

関連項目

印刷のコード例は、『PrintPhoto 』、『Recipes and Printing 』、『UIKit Printing with

UIPrintInteractionControllerandUIViewPrintFormatter 』の各サンプルコードプロジェクトを参照してくだ さい。

(12)

高品質のグラフィックスは、アプリケーションのユーザインターフェイスのなかで重要な部分を占め ます。高品質のグラフィックスを提供することでアプリケーションの外観がよくなるだけでなく、ア プリケーションをシステムのほかの部分の自然な延長のように見せることができます。iOSには、高 品質のグラフィックスを作成するために、Open GLによるレンダリングと、QuartzやCore Animation、 UIKitを使用したネイティブレンダリングという2つの手段が用意されています。この資料では、ネイ ティブレンダリングについて解説します(OpenGLによる描画については、『OpenGL ES Programming Guide for iOS 』を参照)。

Quartzはメインの描画インターフェイスで、パスベースの描画、アンチエイリアスを施したレンダリ ング、グラデーション付き塗りつぶしパターン、画像、カラー、座標空間変換、PDFドキュメントの 作成、表示、解析をサポートします。UIKitは、線画、Quartz画像、およびカラー操作用のObjective-C ラッパーを提供します。Core Animationは、UIKitの多くのビュープロパティについて変更をアニメー ション化するための基盤をサポートします。カスタムアニメーションの実装に使用することもできま す。 この章では、iOSアプリケーションの描画プロセスの概要を取り上げます。また、サポートする描画 テクノロジーごとに、描画テクニックも紹介します。さらに、iOSプラットフォームの描画コードを 最適化するためのヒントやガイダンスも示します。 Important: UIKitのクラスには、スレッドセーフでないものもあります。アプリケーションのメイ ンスレッド以外で描画関連の処理を行う場合は、関係資料を確認してください。

UIKitのグラフィックスシステム

iOSでは、OpenGL、Quartz、UIKit、またはCore Animationのいずれによるものかに関係なく、画面への すべての描画が、UIViewクラスまたはそのサブクラスに属する、インスタンスの領域内で実行され ます。ビューは、描画が実行される、画面内の領域を定義します。システムに用意されているビュー を使用する場合、ビューの描画は自動的に処理されます。しかし、カスタムビューを定義する場合 は、自ら描画コードを用意する必要があります。Quartz、Core Animation、UIKitを使って描画する場 合、以降の各セクションで説明する描画概念を用います。

iOSにおける描画の考え方

(13)

UIKitを使えば、画面に直接描画するだけでなく、オフスクリーンビットマップやPDFグラフィックス コンテキストにも描画できます。オフスクリーンコンテキストに描画するときは、ビューに描画する 場合と違い、ビューの描画サイクルという考え方を意識する必要はありません(あとでその画像を取 得し、画像ビューなどに描画する場合を除く)。

ビューの描画サイクル

UIViewのサブクラスに適用される基本的な描画モデルでは、要求に応じてコンテンツを更新します。 ただし、UIViewクラスでは、更新要求を集め、最も適切なタイミングで描画コードに引き渡すこと により、更新プロセスをより簡単かつ効率的に実行できます。 ビューを最初に描画する、あるいはビューの一部を再描画するときには、iOSがビューのdrawRect: メソッドを呼び出して、コンテンツを描画するよう指示します。 次に示すアクションにより、ビューの更新が引き起こされます。 ● ビューの一部を隠している別のビューの移動または除去 ● hidden非表示になっていたビューの再表示(プロパティをに設定)NO ● ビューを画面外までスクロールし、再び画面内に戻す ● ビューのsetNeedsDisplayメソッドまたはsetNeedsDisplayInRect:メソッドの明示的な呼び出 し システムビューは自動的に再描画されます。カスタムビューの場合、drawRect:メソッドをオーバー ライドし、描画処理をすべてここに実装しなければなりません。このdrawRect:メソッド内で、ネイ ティブの描画技術により、図形、テキスト、画像、グラデーションその他、必要なビジュアルコンテ ンツを描画します。ビューが初めて画面に現れた時点で、iOSはビューのdrawRect:メソッドに、 ビューの可視領域全体を内包する矩形を渡します。それ以降の呼び出しでは、実際に再描画が必要な 部分だけを内包する矩形を渡します。性能を無駄に損なわないよう、内容が変化した部分のみ再描画 してください。 drawRect:メソッドを呼び出した後、ビューは自らを更新済みとしてマークを付け、新たなアクショ ンが到着して別の更新サイクルがトリガされるのを待ちます。ビューに静的コンテンツが表示されて いる場合、必要となるのは、スクロールやほかのビューの存在によって生じる、ビューの見え方の変 化に対応することだけです。 しかし、ビューのコンテンツを変更したい場合は、ビューに対して再描画するよう指示しなければな りません。これは、setNeedsDisplayメソッドまたはsetNeedsDisplayInRect:メソッドを呼び出し て、更新するようトリガを与える、という形で実装します。たとえば、1秒あたり数回コンテンツを 更新する場合、タイマーを設定してビューを更新することができます。また、ユーザの操作やビュー 内での新規コンテンツの作成に応答して、ビューを更新する場合もあります。 UIKitのグラフィックスシステム

(14)

Important: ビューのdrawRect:メソッドを直接呼び出すことは避けてください。このメソッドは、 画面を再描画する際、iOSに組み込まれたコードが呼び出す、という使い方だけ を想定していま す。これ以外の時点ではグラフィックスコンテキストがないので、描画も不可能です(グラフィッ クスコンテキストについては、次の節を参照)。

iOSにおける座標系と描画

iOSではアプリケーションで何かを描画する場合は、座標系で定義される2次元の空間に描画済みのコ ンテンツを配置する必要があります。この概念は、一見簡単そうに思えますが、そうでもありませ ん。iOSのアプリケーションは、描画の際、異なる座標系を扱わなければならないこともあります。 iOSでは、描画はすべてグラフィックスコンテキストに対して行います。グラフィックスコンテキス トとは、どこにどのように描画するか、を記述したオブジェクトと考えるとよいでしょう。描画する 色、クリッピング領域、線幅その他のスタイル情報、フォント情報、合成オプションなど、基本的な 描画属性を定義しています。 さらに、座標系もグラフィックスコンテキストごとに指定できます(図 1-1 (14 ページ)を参照)。 詳しく言うと、各グラフィックスコンテキストには3つの座標系があります。 ● 描画(ユーザ)座標系。描画コマンドを発行する際に使います。 ● ビュー座標系(基底空間)。ビューに対して固定された座標系です。 ● (物理)デバイス座標系。物理画面のピクセルを表します。 図 1-1 描画座標系、ビュー座標系、ハードウェア座標系の関係 UIKitのグラフィックスシステム

(15)

iOSの描画フレームワークは、特定の描画先(画面、ビットマップ、PDFコンテンツ)に描画するため のグラフィックスコンテキストを作成します。そして、これらのグラフィックスコンテキストが、そ の描画先の初期描画座標系を作成します。この初期描画座標系をデフォルト座標系とも呼び、ビュー の基底座標系と1対1で対応します。

各ビューには現在の変換行列(CTM、Current Transformation Matrix)も設定されています。現在の描 画座標系を、(ビューに固定された)ビュー座標系に変換する行列のことです。アプリケーションは この行列を変更することにより、描画処理の動作を変えることができます(詳しくは後述)。 iOSの描画フレームワークは、現在のグラフィックスコンテキストに基づいて、それぞれ1つのデフォ ルト座標系を作成します。iOSには大きく分けて2種類の座標系があります。 ● 左上隅原点(ULO、Upper-Left-Origin)の座標系。描画処理の原点は描画領域の左上隅にあり、座 標値は下および右に向かって大きくなります。UIKitやCore Animationフレームワークのデフォル ト座標系はULOです。 ● 左下隅原点(LLO、Lower-Left-Origin)の座標系。描画処理の原点は描画領域の左下隅にあり、座 標値は上および右に向かって大きくなります。Core Graphicsフレームワークのデフォルト座標系 はLLOです。 座標系については、図 1-2を参照してください。 図 1-2 iOSのデフォルト座標系

UIKit Core Graphics

(0.0, 0.0)

(0.0, 0.0)

(16)

注意: OS Xにおけるデフォルトの座標系はLLOです。Core GraphicsフレームワークとAppKit フレームワークの描画関数や描画メソッドは、完全にこのデフォルト座標系に最適化されて います。ただしAppKitは、この座標系を左上隅原点に反転する機能を提供しています。 ビューのdrawRect:メソッドを呼び出す前に、UIKitは描画処理用のグラフィックスコンテキストを作 成して、画面に描画するためのデフォルト座標系を定めます。ビューのdrawRect:メソッドでは、ア プリケーションは、グラフィックス状態パラメータ(塗りつぶしの色など)を設定して、明示的にそ のパラメータを参照することなく、現在のグラフィックスコンテキストに描画できます。この暗黙の グラフィックスコンテキストは、ULOのデフォルト座標系を作成します。

ポイントとピクセル

iOSでは、描画コードで指定する座標と、デバイス本来のピクセルの間に差異があります。Quartz、 UIKit、Core Animationなどネイティブ描画テクノロジーを使う場合は、描画座標系、ビュー座標系と も、ポイントで距離を表す論理座標空間を使用して座標値を指定します。この論理座標系は、システ ムフレームワークによって画面上のピクセルを管理するために使われるデバイス座標空間とは切り離 されています。 システムはビューの座標空間上のポイントを自動的にデバイス座標空間上のピクセルにマップしま す。ただし必ずしも1対1でマップされるとは限りません。この動作の結果として、常に留意すべき、 ある重要な事実が生じます。 1ポイントが必ずしも1物理ピクセルに対応しているとは限りません。 ポイント(および論理座標系)を使用する目的は、デバイスに依存しない一貫性のある出力サイズを 提供することです。多くの場合、ポイントの実際のサイズは重要ではありません。ポイントの目的 は、ビューやレンダリングしたコンテンツのサイズと位置を指定するために、コードの中で使用でき る比較的一貫した尺度を提供することです。ポイントがピクセルに実際にマップされる仕組みは、シ ステムフレームワークによって処理される詳細部分です。たとえば、高解像度画面のデバイスでは、 1ポイント幅の線は、実際には2物理ピクセル幅の線になります。その結果、類似の2つのデバイス(そ のうちの一方だけが高解像度画面を持つ)に同じコンテンツを描画した場合、コンテンツはどちらの デバイス上でもほとんど同じサイズのように見えます。

iOSでは、UIScreen、UIView、UIImage、CALayerの各クラスを使用して、特定のオブジェクトのポ

イントとピクセルの関係を示す倍率を取得(場合によっては設定も)することができます。たとえば UIKitのビューにはcontentScaleFactorプロパティがあります。標準解像度の画面では、倍率は通常

1.0です。高解像度画面では一般に2.0です。将来、他の倍率の画面が使われるようになる可能性もあ ります(iOS 4より前のバージョンでは、この倍率は1.0であることが前提でした)。

(17)

Core Graphicsなどのネイティブ描画技術は、この倍率を加味して処理するようになっています。たと えば、ビューの1つがdrawRect:メソッドを実装していれば、UIKitは自動的にそのビューの倍率を画 面の倍率に設定します。さらにUIKitは、ビューの倍率に対応するために、描画中に使用されるあらゆ るグラフィックスコンテキストの現在の変換行列を自動的に変更します。このため、drawRect:メ ソッドで描画するコンテンツはすべて、デバイス本来の画面に合うように拡大縮小されます。 この自動マッピングの働きにより、描画コードを記述する際、通常は ピクセルを意識する必要があり ません。しかし、ポイントからピクセルへの変換方法に応じて、描画方法を変えなければならないこ ともあります。高解像度画像を高解像度画面つきのデバイスにダウンロードする、あるいは、低解像 度画面に描画する際、変換による歪みを避けたい、などの場合です。 iOSのグラフィックスサブシステムは、画面に描画する際、アンチエイリアシングという技術を使っ て、高解像度画像を低解像度画面に、近似的に再現しようとします。これは実例を使って説明すると 分かりやすいでしょう。真っ白な背景に黒の垂直線を描画する場合、その線がちょうどピクセル上に 乗っていれば、白地に黒のピクセルを並べて表示します。一方、2つのピクセルのちょうど中間に当 たる場合は、灰色のピクセルを2列分並べて表示します(図 1-3を参照)。 図 1-3 1ポイント幅の線を、その中心のポイント値が整数であるように描画した様子 ポイント値が整数である位置は、2つのピクセルの境界(ちょうど中間)に当たります。たとえば、 1ピクセル幅の垂直線を(1.0, 1.0)から(10.0, 10.0)に向かって引けば、灰色のピクセルで描画され た線になります。一方、2ピクセル幅であれば、真っ黒の線になります。2列分のピクセル全体を覆う ように塗りつぶすことになるからです。描画方法の規則として、物理ピクセル幅が奇数である線は、 偶数の線に比べて淡い色になります(ピクセル全体を覆うよう位置をずらした場合を除く)。 倍率が問題になるのは、1ポイント幅の線が何ピクセルを覆うか、を判断するときです。 UIKitのグラフィックスシステム

(18)

低解像度ディスプレイ(倍率は1.0)であれば、1ポイント幅の線は1ピクセル幅になります。1ポイン ト幅の水平線や垂直線を描画する際、アンチエイリアシングを避けるためには、線幅(ピクセル)が 奇数ならば位置に0.5ポイントを加えて、線の両端の位置(ポイント)が整数になるよう調整しなけれ ばなりません。一方、偶数であれば、淡い線になってしまわないよう、この処理はしない でくださ い。 図 1-4 1ポイント幅の線の描画状態:標準ディスプレイとRetinaディスプレイ 高解像度ディスプレイ(倍率は2.0)の場合、1ポイント幅の線にアンチエイリアシングが適用される ことはありません。(-0.5~+0.5の)2ピクセル全体の幅を占めるからです。1物理ピクセルだけを覆 う線を描画するためには、幅を0.5ポイントとし、位置を0.25ポイントずらす必要があります。2種類 の画面の比較を図 1-4に示します。 もちろん、倍率に応じて描画特性を変更すると、予期せぬ結果が生じる可能性があります。1ピクセ ル幅の線は、デバイスによってはきれいに表示されるかもしれませんが、高解像度デバイス上では細 すぎてはっきりと見えにくくなる可能性があります。このような変更を行うかどうかの判断はデベ ロッパに任されています。

グラフィックスコンテキストを取得する

多くの場合、グラフィックスコンテキストはあらかじめ設定済みになっています。各ビューオブジェ クトが自動的にグラフィックスコンテキストを生成するので、drawRect:メソッドは、呼び出される とすぐに描画処理を開始できます。描画環境の設定の一環として、UIViewクラスは、現在の描画環 境に対応するグラフィックスコンテキスト(CGContextRef不透過型)を作成します。 ビュー以外に描画する(PDFに一連の描画コマンドを出力する、ビットマップファイルに描画結果を 出力する、など)、あるいはコンテキストオブジェクトを引数とするCore Graphics関数を呼び出す場 合、グラフィックスコンテキストオブジェクトを取得する必要があります。以下、その方法を説明し ます。 UIKitのグラフィックスシステム

(19)

グラフィックスコンテキスト、グラフィックスの状態情報の修正、グラフィックスコンテキストを使 用したカスタムコンテンツの作成の詳細については、『Quartz 2D Programming Guide 』を参照してく ださい。グラフィックスコンテキストと一緒に使用する関数の一覧については、『CGContext

Reference 』、『CGBitmapContext Reference 』、『CGPDFContext Reference 』を参照してください。

画面への描画

drawRect:、またはその他のメソッド内で、Core Graphics関数を使用してビューに描画する場合は、

描画用のグラフィックスコンテキストが必要になります(これらの関数のほとんどで、第1パラメー タはCGContextRefオブジェクトでなければなりません)。UIGraphicsGetCurrentContext関数を 呼び出すと、drawRect:内で暗黙的に作成されたものと同じグラフィックスコンテキストの明示的な バージョンを取得できます。同じグラフィックスコンテキストであるため、描画関数もULOのデフォ ルト座標系を参照しなければなりません。 Core Graphics関数を使用してUIKitビューに描画する場合は、描画操作にはUIKitのULO座標系を使用し なければなりません。あるいは、CTMに反転変換を適用して、Core GraphicsのネイティブのLLO座標系 を使用して、UIKitビューにオブジェクトを描画することもできます。反転変換の詳細については、“デ フォルト座標系の反転” (25 ページ)で説明します。 UIGraphicsGetCurrentContext関数は、必ず有効なグラフィックスコンテキストを返します。たと えば、PDFコンテキストを作成してUIGraphicsGetCurrentContextを呼び出すと、PDFコンテキスト

が返されます。Core Graphics関数を使用してビューに描画する場合は、UIGraphicsGetCurrentContext

によって返されたグラフィックスコンテキストを使用しなければなりません。 注意: UIPrintPageRendererクラスには、印刷可能なコンテンツを描画するためのメソッ ドがいくつか宣言されています。drawRect:と同様に、UIKitには、これらのメソッドの実装 用に暗黙のグラフィックスコンテキストが含まれています。このグラフィックスコンテキス トは、ULOのデフォルト座標系を作成します。

ビットマップコンテキストやPDFコンテキストへの描画

UIKitは、ビットマップグラフィックスコンテキストに画像をレンダリングする関数と、PDFグラフィッ クスコンテキストに描画することによって、PDFコンテンツを生成する関数を提供しています。どち らのアプローチの場合も、最初にグラフィックスコンテキスト(ビットマップコンテキスト、または PDFコンテキスト)を作成する関数を呼び出す必要があります。返されるオブジェクトは、その後の 描画や状態設定呼び出しのための、現在の(暗黙の)グラフィックスコンテキストとしての役割を果 たします。グラフィックスコンテキストでの描画が終了したら、別の関数を呼び出してコンテキスト を閉じます。 UIKitのグラフィックスシステム

(20)

UIKitが提供するビットマップコンテキストもPDFコンテキストも、ULOのデフォルト座標系を作成し ます。Core Graphicsには、ビットマップグラフィックスコンテキストに描画する関数に相当する関数 と、PDFグラフィックスコンテキストに描画する関数に相当する関数があります。しかし、Core Graphics を通じてアプリケーションが直接作成したコンテキストは、LLOのデフォルト座標系を作成します。 注意: iOSでは、ビットマップコンテキストやPDFコンテキストへの描画には、UIKitの関数を 使用することをお勧めします。ただし、Core Graphicsの代替関数を使用し、描画結果を表示 することを意図している場合は、デフォルト座標系の違いを補正するようにコードを調整す る必要が生じます。詳細については、“デフォルト座標系の反転” (25 ページ)を参照して ください。 詳しくは、“画像の描画と生成” (40 ページ)(ビットマップコンテキストへの描画)、“PDFコンテ ンツの生成” (45 ページ)(PDFコンテキストへの描画)を参照してください。

色と色空間

iOSは、Quartzで利用可能な最大限の色空間をサポートしていますが、ほとんどのアプリケーションで 必要となるのはRGB色空間だけです。iOSは組み込みハードウェアで実行され、画面にグラフィックス を表示するよう設計されているため、RGB色空間が最適な色空間です。 UIColorオブジェクトは、RGB、HSB、グレイスケールの値を使用してカラー値を指定できる簡易メ ソッドを備えています。この方法で色を作成する場合、色空間を指定する必要はありません。色空間 は、UIColorオブジェクトが自動的に決定してくれます。

Core Graphicsフレームワークでは、CGContextSetRGBStrokeColor関数および

CGContextSetRGBFillColor関数を使用して色を作成し、設定することもできます。Core Graphicsフ レームワークには、ほかの色空間を使用して色を作成したり、カスタム色空間を作成する機能もあり ますが、描画コードでこれらの機能を使用することはお勧めしていません。描画コードでは常にRGB カラーを使用してください。

QuartzとUIKitを使用した描画

Quartzとは、iOSにおけるネイティブの描画テクノロジーを表す総称です。Core Graphicsフレームワー クは、Quartzの核を構成し、コンテンツの描画に使用される主要インターフェイスです。このフレー ムワークは、以下を操作するためのデータ型と関数を提供します。 ● グラフィックスコンテキスト ● パス QuartzとUIKitを使用した描画

(21)

● 画像とビットマップ ● 透明レイヤ ● 色、パターン色、色空間 ● グラデーションと陰影 ● フォント ● PDFコンテンツ UIKitは、グラフィックス関連の操作に焦点を合わせた各種クラスを提供し、Quartzの基本機能に基づ いて構成されています。UIKitのグラフィックスクラスは、描画ツールの総合セットを意図したもので はありません。その役割はCore Graphicsがすでに担っています。代わりに、UIKitグラフィックスクラ スは、ほかのUIKitクラスの描画をサポートします。UIKitのサポート機能には、次のクラスと関数が含 まれます。 ● UIImage。画像を表示する不変クラスを実装します。 ● UIColor。デバイスカラーの基本サポートを提供します。 ● UIFont。フォント情報を必要とするクラスにフォント情報を提供します。 ● UIScreen。画面に関する基本情報を提供します。 ● UIBezierPath。線、円弧、楕円、その他の図形を描画できるようにします。 ● UIImageオブジェクトをJPEG形式またはPNG形式で生成する関数 ● ビットマップグラフィックスコンテキストに描画する関数 ● PDFグラフィックスコンテキストに描画することによって、PDFデータを生成する関数 ● 矩形を描画する関数および描画領域をクリッピングする関数 ● 現在のグラフィックスコンテキストを変更したり、取得する関数

UIKitを構成するクラスとメソッドの詳細については、『UIKit Framework Reference 』を参照してくださ い。Core Graphicsフレームワークを構成する不透過型と関数の詳細については、『Core Graphics Framework Reference 』を参照してください。

グラフィックスコンテキストの設定

drawRect:メソッドが呼び出されるまでに、ビューオブジェクトはグラフィックスコンテキストの生 成し、現在のコンテキストとして設定しています。このコンテキストが存在するのは、drawRect:が 呼び出されている間だけです。このグラフィックスコンテキストへのポインタは、 UIGraphicsGetCurrentContext関数を呼び出して取得できます。この関数は、CGContextRef型へ の参照を返します。この参照を、Core Graphics関数に渡して現在のグラフィックス状態を変更しま QuartzとUIKitを使用した描画

(22)

す。表 1-1に、グラフィックス状態の変更に使用する主な関数を示します。すべての関数の一覧につ いては、『CGContext Reference 』を参照してください。この表は、UIKitに代替できるものがあれば、 それも示しています。 表 1-1 グラフィックスの状態を変更するCore Graphics関数 UIKitの代替 Core Graphics関数 グラフィックスの状態 なし CGContextRotateCTM CGContextScaleCTM CGContextTranslateCTM CGContextConcatCTM 現在の変換行列(CTM) UIRectClip関数 CGContextClipToRect クリッピング領域 なし CGContextSetLineWidth CGContextSetLineJoin CGContextSetLineCap CGContextSetLineDash CGContextSetMiterLimit 線:幅、結合、キャップ、ダッ シュ、マイター上限 なし CGContextSetFlatness 曲線推定の精度 なし CGContextSetAllows-Antialiasing アンチエイリアスの設定 UIColorクラス CGContextSetRGBFillColor CGContextSetRGBStrokeColor 色:塗りつぶしとストロークの 設定 なし CGContextSetAlpha グローバルなアルファ値(透明 度) なし CGContextSetRenderingIntent レンダリングインテント UIColorクラス CGContextSetFillColorSpace CGContextSetStrokeColorSpace 色空間:塗りつぶしとストロー クの設定 UIFontクラス CGContextSetFont CGContextSetFontSize CGContextSetCharacterSpacing テキスト:フォント、フォント サイズ、文字間のスペース、テ キスト描画モード QuartzとUIKitを使用した描画

(23)

UIKitの代替 Core Graphics関数 グラフィックスの状態 UIImageクラスと各 種描画関数を使用し て、使用するブレン ドモードを指定する ことができます。 CGContextSetBlendMode ブレンドモード グラフィックスコンテキストには、保存されたグラフィックス状態のスタックがあります。グラフィッ クスコンテキストを生成した時点では、スタックは空です。CGContextSaveGState関数を使用する と、現在のグラフィックス状態のコピーがスタックにプッシュされます。以後、グラフィックス状態 に加えた変更はその後の描画操作に影響を与えますが、スタックに格納されたコピーには影響しませ ん。変更が完了した時点で、CGContextRestoreGState関数を使用して、保存されている状態をス タックの一番上からポップすることにより、前のグラフィックス状態に戻ることができます。このよ うにグラフィックス状態をプッシュしたり、ポップしたりする方法は、前の状態にすばやく戻る方法 であり、状態の変更を個別に取り消す必要をなくします。この方法は、状態の特定の側面(クリッピ ングパスなど)を元の設定に復元するただ1つの方法でもあります。 グラフィックスコンテキストの概要およびグラフィックスコンテキストを使用した描画環境の設定に ついては、『“Graphics Contexts”「Graphics Contexts」Quartz 2D Programming Guide を参照してください。

パスの作成と描画

パスとは、連続する直線とベジェ曲線から生成される、ベクトルベースの形状のことです。UIKitに は、ビュー内に矩形などの単純なパスを描画するためのUIRectFrame関数とUIRectFill関数が含ま

れています。Core Graphicsにも、矩形や楕円といった単純なパスを作成するための簡易関数が含まれ ています。

より複雑なパスの場合は、UIKitのUIBezierPathクラスか、Core GraphicsフレームワークのCGPathRef

不透過型を対象とする関数を使用して、自らパスを作成する必要があります。どちらのAPIを使って も、グラフィックスコンテキストなしでパスを組み立てることは可能ですが、パス上の点は現在の座 標系(ULO、LLOのいずれか)で表す必要があり、実際にレンダリングする際にはやはりグラフィッ クスコンテキストが必要です。 パスを描画する際には、現在のコンテキストセットが必要です。カスタムビューの(drawRect:で有 効になる)コンテキスト、ビットマップコンテキスト、PDFコンテキストのどれでも構いません。座 標系によってパスの実際のレンダリング結果が決まります。UIBezierPathはULO座標系を前提とし ています。したがって、ビューが反転している(LLO座標系である)場合、意図と異なる結果になっ てしまいます。最良の結果を得るには、常に、レンダリングに使用するグラフィックコンテキストの 現在の座標系の原点に基づいて点を指定する必要があります。 QuartzとUIKitを使用した描画

(24)

注意: 円弧のパスの場合は、この「ルール」に従っていても追加作業が必要です。ULO座標 系に点を配置するCore Graphic関数を使用してパスを作成し、その後でパスをUIKitビューに 描画すると、円弧が「指す」向きが異なります。詳細については、“異なる座標系での描画 による副作用” (26 ページ)を参照してください。

iOSでパスを作成する場合は、Core Graphicsだけが提供する機能(パスへの楕円の追加など)が必要で ない限り、CGPath関数ではなく、UIBezierPathを使用することをお勧めします。UIKitでパスを作成

して描画する方法の詳細については、“ベジエパスを使用した図形の描画” (30 ページ)を参照して ください。

UIBezierPathを使用してパスを描く方法の詳細については、“ベジエパスを使用した図形の描

画” (30 ページ)を参照してください。複雑なパス要素を構成する点を指定する方法を含め、Core Graphicsを使用してパスを描く方法の詳細については、『“Paths”「Paths」Quartz 2D Programming Guide を参照してください。パスの作成に使用する関数については、『CGContextReference 』および『CGPath Reference 』を参照してください。

パターン、グラデーション、陰影の作成

Core Graphicsフレームワークには、パターン、グラデーション、陰影を作成する関数も用意されていま す。これらはモノクロ以外の色の作成や、作成したパスの塗りつぶしに使用します。パターンは画像 やコンテンツの繰り返しを元に作成します。グラデーションと陰影はそれぞれ、色から色への滑らか な移り変わりを生み出すことができます。

パターン、グラデーション、陰影の作成と使用の詳細については、『Quartz 2D Programming Guide 』 を参照してください。

座標系のカスタマイズ

デフォルトでUIKitが生成するCTMは、ポイントを直接ピクセルに対応づけるものです。そのままです べて描画しても構いませんが、CTMを変更すると便利な場合があります。 ビューのdrawRect:メソッドが最初に呼び出される際、座標系の原点がビューの原点と一致し、X軸 が右、Y軸が下の方向に伸びるよう、CTMが設定されます。ただし、CTMに、拡大縮小、回転、変換な どの係数を追加して変更を加えて、サイズ、向き、そして基盤になるビューやウインドウを基準にし たデフォルトの座標系の位置を変更することができます。 QuartzとUIKitを使用した描画

(25)

座標変換の機能を使って描画性能を改善する

CTMを変更するという技法は、ビューに描画する手段として標準的に利用されています。一度生成し たパスを繰り返し使え、したがって描画に必要な計算量を減らせるからです。たとえば、座標点(20, 20)から始まる正方形を描画する場合、(20, 20)に移動するパスを作成した後、必要な直線をひととお り描画して正方形を完成させます。しかし、この正方形を後で点(10, 10)まで移動することにした場合 は、新たな開始点を指定してパスを作成し直す必要があります。パスの作成は負担の多い操作なの で、原点が(0, 0)の正方形を作成し、望みの描画原点に一致するようCTMを変更する、という方法を推 奨します。

Core Graphicsフレームワークでは、CTMに変更を加える方法が2通りあります。1つは、『CGContext Reference 』で定義されているCTM操作関数を使用して直接変更する方法です。もう1つは、

CGAffineTransform構造体を作成し、望みの変換を適用してその変換をCTMに反映させる方法です。

アフィン変換を使用して変換をグループとしてひとまとめにし、それらの変換をCTMに一度に適用す ることができます。また、アフィン変換を評価、反転し、その結果を用いてコード内の点、サイズ、 矩形の値を変更することもできます。アフィン変換については、『Quartz 2D Programming Guide 』お よび『CGAffineTransform Reference 』を参照してください。

デフォルト座標系の反転

UIKitによる描画を反転させるには、LLO座標系の描画環境を、UIKitのデフォルト座標系に調整するよ うにCALayerを変更します。描画用にUIKitのメソッドと関数のみを使用する場合は、CTMを反転させ

る必要はありません。しかし、UIKitの呼び出しとCore GraphicsやImage I/Oの関数呼び出しが混在する 場合は、CTMの反転が必要になることがあります。 特に、Core Graphics関数を直接呼び出して画像やPDFドキュメントを作成すると、ビューのコンテキ ストにはオブジェクトが逆さまにレンダリングされます。画像やページを正しく表示するには、CTM を反転させる必要があります。 Core Graphicsのコンテキストに描画されたオブジェクトを、UIKitビューに適切に表示されるように反 転させるには、次の2つの手順でCTMを修正しなければなりません。原点を描画領域の左上角に変換 します。次に、倍率変換を適用して、y軸に-1を掛けます。これを実行するコードは、次のようにな ります。 CGContextSaveGState(graphicsContext); CGContextTranslateCTM(graphicsContext, 0.0, imageHeight); CGContextScaleCTM(graphicsContext, 1.0, -1.0);

CGContextDrawImage(graphicsContext, image, CGRectMake(0, 0, imageWidth, imageHeight));

CGContextRestoreGState(graphicsContext); QuartzとUIKitを使用した描画

(26)

Core Graphicsの画像オブジェクトで初期化されたUIImageオブジェクトを作成すると、UIKitが反転変

換を実行します。どのUIImageオブジェクトもCGImageRef不透過型に基づいています。CGImageプロ

パティを利用してCore Graphicsオブジェクトにアクセスして、その画像に対して何らかの処理を行う ことができます(Core Graphicsには、UIKitでは利用できない画像関連機能があります)。処理が終了 したら、変更後のUIImageオブジェクトからCGImageRefオブジェクトを再作成できます。

注意: Core GraphicsのCGContextDrawImage関数を使用すると、任意のレンダリング先に画

像を描画できます。この関数には2つのパラメータがあります。1つはグラフィックスコンテ キスト、もう1つは、画像のサイズと、ビューなどの描画サーフェスでの位置の両方を定義 した矩形です。CGContextDrawImageを利用して画像を描画している場合は、現在の座標系 をLLOの向きに調整しないと、UIKitビューでは画像が逆さまに表示されます。また、この関 数に渡す矩形の原点は、この関数が呼び出されたときの現在の座標系の原点になります。

異なる座標系での描画による副作用

ある描画テクノロジーのデフォルト座標系でオブジェクトを描画してから、別の描画テクノロジーの グラフィックスコンテキストでそれをレンダリングしたときに、描画の異常が発覚することもありま す。このような副作用を考慮してコードを調整できます。 円弧と回転

CGContextAddArcやCGPathAddArcなどの関数を利用してパスを描画したときに、LLO座標系を想定

している場合、その円弧をUIKitビューに正しくレンダリングするには、CTMを反転させる必要があり ます。しかし同じ関数を使用して、ULO座標系に点が配置された円弧を作成した後でそのパスをUIKit ビューにレンダリングすると、元の円弧から変更されていることが分かります。円弧の終点は、 UIBezierPathクラスを使用して作成した円弧の終点とは反対の向きを指しているはずです。たとえ ば、下向きの矢印は上を指し(図 1-5を参照)、弧の曲がりの向きも異なっています。Core Graphics で描画した円弧の向きを、ULO座標系に合わせて変更しなければなりません。この向きは、これらの 関数のstartAngleパラメータとendAngleパラメータによって制御します。 図 1-5 Core GraphicsおよびUIKitでレンダリングした弧の向き

Arc rendered in UIKit Arc specified in Core Graphics

y y x (0,0) (0,0) x QuartzとUIKitを使用した描画

(27)

オブジェクトを回転した場合も、同様の鏡像効果が生じる場合があります(たとえば、

CGContextRotateCTMを呼び出した場合)。ULO座標系を参照するCore Graphics関数呼び出しを使用

してオブジェクトを回転すると、UIKitにレンダリングしたときのオブジェクトの向きは逆になりま す。コードでは、回転による向きの違いを考慮しなければなりません。それには、CGContextRotateCTM を利用して、angleパラメータの符号を反転させます(たとえば、負の値を正の値にします)。 影 オブジェクトから影が落ちる方向はオフセット値によって指定され、そのオフセット値の解釈は描画 フレームワークの規約によります。UIKitでは、xとyの正のオフセット値によって、オブジェクトの右 下に影が作成されます。Core Graphicsでは、xとyの正のオフセット値によって、オブジェクトの右上 に影が作成されます。UIKitのデフォルト座標系を持つオブジェクトの位置を揃えるためにCTMを反転 しても、オブジェクトの影には作用しません。このため、影は正しくオブジェクトを追跡しません。 正しく追跡できるようにするには、オフセット値を現在の座標系に合うように変更する必要がありま す。

注意: iOS 3.2より前は、Core GraphicsとUIKitは、影の方向に関して同じ規約(正のオフセッ ト値によってオブジェクトの右下に影が作成される)を使用していました。

Core Animation効果の適用

Core AnimationはObjective-Cフレームワークで、滑らかなリアルタイムアニメーションをすばやく簡単 に作成する基盤を提供します。Core Animation自体は、形状や画像、その他のタイプのコンテンツを 作成する基本ルーチンを提供するわけではないという点で、描画テクノロジーではありません。その 代わりに、別のテクノロジーを使用して作成したコンテンツを操作したり、表示したりするためのテ クノロジーであるといえます。 ほとんどのアプリケーションでは、iOSで何らかの形でCore Animationを利用するこによってメリット があります。アニメーションは、今起きていることをユーザに伝えるフィードバックの働きがありま す。たとえば、ユーザが「設定(Settings)」アプリケーションを操作するとき、ユーザが環境設定の下 位階層に進んだり、ルート階層に戻ったりするのに合わせて、画面が視野にすべり込んだり、視野か らすべり出たりします。この種のフィードバックは重要で、ユーザに対して文脈情報を提供します。 アニメーションは、アプリケーションの見た目を充実させる働きもあります。 ほとんどの場合、ごくわずかな労力でCore Animationのメリットを享受することができます。たとえ ば、UIViewクラスのいくつかのプロパティ(ビューのフレーム、中心、色、不透明度など)につい て、値が変化するとアニメーションが開始するように設定できます。UIKitにこれらのアニメーション を実行するように伝えるために、一定の作業が必要となりますが、アニメーション自体は自動的に作 成され、実行されます。組み込みのビューアニメーションをトリガする方法については、『』のin UIView Class Reference 「Animating Views」UIView Class Reference を参照してください。

(28)

基本アニメーションからさらに充実させるには、Core Animationのクラスやメソッドを直接扱う必要 があります。以降の各セクションでは、Core Animationに関する情報を紹介し、iOSにおいて、Core Animationのクラスやメソッドを使用して典型的なアニメーションを作成する方法について説明しま す。Core Animationの詳細と使用方法については、『Core Animation Programming Guide 』を参照して ください。

レイヤについて

Core Animationにおける重要なテクノロジーがレイヤオブジェクトです。レイヤは、ビューに性質がよ く似た軽量オブジェクトですが、実際には、表示するコンテンツのジオメトリやタイミング、視覚的 プロパティをカプセル化する、モデルオブジェクトです。コンテンツは、次に示す3つのうち、いずれ かの方法で提供されます。 ● CGImageRefをレイヤオブジェクトのプロパティに割り当てることができます。contents ● デリゲートをレイヤに割り当てて、デリゲートに描画を処理させることができます。 ● CALayerをサブクラス化し、表示メソッドの1つをオーバーライドすることができます。 レイヤオブジェクトのプロパティを操作すると、実際に操作されるのはモデルレベルのデータで、こ のデータによって、関連付けられているコンテンツの表示方法が決まります。そのコンテンツの実際 のレンダリングはコードとは別に処理され、高速にレンダリングされるよう徹底して最適化されま す。デベロッパは、レイヤコンテンツとアニメーションプロパティを設定するだけでよく、あとは Core Animationが引き継いで処理してくれます。

レイヤおよびその使い方については、『Core Animation Programming Guide 』を参照してください。

アニメーションについて

レイヤのアニメーション化では、Core Animationは独立したアニメーションオブジェクトを使用して アニメーションのタイミングと動作を制御します。CAAnimationクラスとそのサブクラスにより、 コード内で使用可能なさまざまな種類のアニメーション動作が提供されます。ある値から別の値へと プロパティを移行させるシンプルなアニメーションを作成することも、指定した値とタイミング関数 を通じてアニメーションを追跡する、複雑なキーフレームアニメーションを作成することもできま す。 Core Animationでは、複数のアニメーションをトランザクションと呼ばれる単位にまとめることもで きます。CATransactionオブジェクトは、アニメーションのグループを1つの単位として扱います。 このクラスのメソッドを使用して、アニメーションの再生時間を設定することもできます。 カスタムアニメーションを作成する方法については、『AnimationTypesandTimingProgrammingGuide 』 を参照してください。 Core Animation効果の適用

(29)

Core Animationレイヤの倍率の考慮

Core Animationレイヤを直接使用してコンテンツを提供するアプリケーションは、倍率を計算に入れ るために描画コードを調整しなければならないことがあります。通常、ビューのdrawRect:メソッ ド、またはレイヤのデリゲートのdrawLayer:inContext:メソッドで描画する際、システムは自動的 に倍率を計算に入れるためにグラフィックスコンテキストを調整します。しかし、ビューが次のいず れかを行う場合、倍率を認識したり変更したりすることが必要になることもあります。 ● 倍率の異なる追加のCore Animationレイヤを作成し、それらをビューのコンテンツに合成する ● Core Animationレイヤのcontentsプロパティを直接設定する

Core Animationの合成エンジンは、各レイヤのcontentsScaleプロパティを見てそのレイヤのコンテ

ンツを合成時に拡大縮小する必要があるかを判断します。アプリケーションがビューに関連付けられ ていないレイヤを作成する場合、新しいレイヤオブジェクトの倍率は最初はそれぞれ1.0に設定されま す。倍率を変更しないまま、高解像度画面上でその後にレイヤを描画した場合、レイヤのコンテンツ は倍率の相違を補うために自動的に拡大縮小されます。コンテンツを拡大縮小したくない場合は、 contentsScaleプロパティの値を設定することにより、レイヤの倍率を2.0に変更することができま すが、高解像度のコンテンツを指定せずに変更すると、既存のコンテンツは期待していたよりも小さ く見える可能性があります。このような問題を修正するには、そのレイヤに対して高解像度のコンテ ンツを用意する必要があります。 Important: レイヤのcontentsGravityプロパティには、標準解像度のレイヤコンテンツが高解像 度画面で拡大縮小されるかどうかを決める際に使われます。このプロパティの値は、デフォルト ではkCAGravityResizeに設定され、レイヤコンテンツはレイヤの境界内に納まるように拡大縮小 されます。これをサイズ変更しない選択肢に変更すると、自動的な拡大縮小は行われなくなりま す。このような状況では、それに応じてアプリケーションのコンテンツまたは倍率を調整する必 要があります。 レイヤのコンテンツを異なる倍率に合うように調整することは、レイヤのcontentsプロパティを直 接設定する場合に行うのが最も適切です。Quartz画像には倍率の概念はないため、直接ピクセルを操 作します。このため、レイヤのコンテンツ用のCGImageRefオブジェクトを作成する前に、倍率を確 認して、それに応じて画像サイズを調整します。具体的には、アプリケーションバンドルから適切な サイズの画像を読み込むか、または、UIGraphicsBeginImageContextWithOptions関数を使用して 倍率がレイヤの倍率と一致する画像を作成します。高解像度画像を作成しない場合は、先述のとおり 既存のビットマップを拡大縮小してもかまいません。 高解像度画像の指定とロードの方法に関する詳細については、“アプリケーションへの画像の読み込 み” (86 ページ)を参照してください。高解像度画像の作成方法に関する詳細については、“ビット マップコンテキストやPDFコンテキストへの描画” (19 ページ)を参照してください。 Core Animation効果の適用

図 5-2 プリンタオプションのPopoverビュー(iPad) 53 図 5-3 プリンタオプションページ(iPhone) 54 図 5-4 Print Center 55 図 5-5 Print Center:印刷ジョブの詳細 56 図 5-6 印刷のアーキテクチャ 57 図 5-7 UIKitの印刷オブジェクトの関係 58 図 5-8 複数ページの印刷ジョブのレイアウト 66 表 5-1 アプリケーションコンテンツの印刷方法の決定 59 リスト 5-1 ページ範囲の選択が可能な単一のPDFドキュメント

参照

関連したドキュメント

工場設備の計測装置(燃料ガス発熱量計)と表示装置(新たに設置した燃料ガス 発熱量計)における燃料ガス発熱量を比較した結果を図 4-2-1-5 に示す。図

分類記号  構 造 形 式 断面図 背面土のタイプ.. GW-B コンクリートブロック重力式

aTheTateModem3)4)5)(図6,7,8,9,10):ロン

[印刷]ボタンを押下すると、印刷設定画面が起動します。(「3.1.7 印刷」参照)

7 号機原子炉建屋(以下「K7R/B」という。 )の建屋モデル及び隣接応答倍率を図 2-1~図 2-5 に,コントロール建屋(以下「C/B」という。

第 25 サイクルから第 27 サイクルの炉心について,サイクル初期とサイクル末期の減 速材ボイド係数を図 3.2-5(1)〜図 3.2-5(2)示す。第 25 サイクルから第

目印3 目印4 目印5 目印6 目印7. 先端の重り12

区部台地部の代表地点として練馬区練馬第1観測井における地盤変動の概 念図を図 3-2-2 に、これまでの地盤と地下水位の推移を図