Text Kitによるテキストレイアウト(後編)[2ページ目]

テキストコンテナの生成は、次のプライベートメソッドにより行います。

[ソースコード45] テキストコンテナの生成

- (void)createContainers
{
  // 最終コンテナに含まれるグリフ範囲を示す
  NSRange range = NSMakeRange(0, 0);
  
  // 最終コンテナに含まれるグリフインデックスの最大値と
  // レイアウトマネージャが持つグリフ数を比較
  while (NSMaxRange(range) < self.layoutManager.numberOfGlyphs) {
      // テキストコンテナの生成
      NSTextContainer *container =
      [[NSTextContainer alloc] initWithSize:self.containerSize];
      // レイアウトマネージャにテキストコンテナを追加
      [self.layoutManager addTextContainer:container];
      // 作成したテキストコンテナに含まれるグリフ範囲を取得
      // →ループの条件判断に戻る
      range = [self.layoutManager glyphRangeForTextContainer:container];
  }
}

上記コードでは、テキストコンテナを作成してレイアウトマネージャに追加する処理を繰り返しています。十分な数のコンテナを作成できたかは、グリフ数(文字数とは異なるテキストコンテンツの長さ)を元に判断します。
レイアウトマネージャにテキストコンテナを追加したら、そのコンテナに含まれるグリフの範囲を取得します。グリフ範囲の最大インデックスは、それまでに作成したコンテナに格納されるグリフ数を意味します。したがって、このグリフインデックスとレイアウトマネージャが持つグリフ数(全テキストコンテンツを示す)を比較すれば、コンテナ数が十分であるか判断できます。レイアウトマネージャが持つグリフ数が大きければ、コンテナ数が不足しているので、さらにコンテナを作り続けます。
これで、必要な数のテキストコンテナを生成することができます。
なお、ここではcontainerSizeはreadonlyとして、初期化時に指定していますが、動的にコンテナサイズの変更が必要になる場合は適宜置き換えてください。
例えば、デバイスの回転でテキストビューのサイズが変更になるケースでは、コンテナサイズも変更する必要があります。コンテナサイズが変更されたら、レイアウトマネージャが持つテキストコンテナも生成し直す必要があります。また、表示コンテンツとなるtextStorageが変更になった場合も同様に、コンテナの再生成が必要となります。

最後に、TextModelを使用したUITextViewの作成例を示します。
テキストコンテンツを表示するには、UITextViewを生成する際にTextModelが管理するレイアウトマネージャからテキストコンテナを取得し、テキストビューと対応付ければ該当ページのUITextViewが作成できます。
例えば、1ページ目(ページインデックス0)を表示するUITextViewの生成は、下記の通りです(ソースコード9.46)。

[ソースコード46] UITextViewの生成

CGRect textViewRect = ...;
CGSize textViewSize = textViewRect.size;
UIEdgeInsets containerInset = UIEdgeInsetsMake(10, 10, 10, 10);
CGSize containerSize = 
CGSizeMake(textViewSize.width - containerInset.left - containerInset.right,
           textViewSize.height - containerInset.top - containerInset.bottom);
  
self.model = [[TextModel alloc] initWithContainerSize:containerSize];

// ページインデックス0のテキストコンテナを取得
NSTextContainer *textContainer = self.model.layoutManager.textContainers[0];
// テキストコンテナを指定してUITextViewを生成
UITextView *textView = [[UITextView alloc] initWithFrame:textViewRect 
                                           textContainer:textContainer];
textView.textContainerInset = containerInset;

なお、既に説明した通り、テキストコンテナはUITextViewの生成時にしか設定できません。StoryboardなどでUITextViewを配置する場合は、独自のテキストコンテナは使用できないので注意してください。

この記事のもとになった書籍
UIKit徹底解説 iOSユーザーインターフェイスの開発

西方 夏子 著/丸山 弘詩 編
価格:3,800円+税
発売日:2014年06月13日発売
ISBN:978-4-8443-3608-2
発行:インプレスジャパン

UIKit徹底解説 iOSユーザーインターフェイスの開発

ユーザーインターフェイス(UI)を制御するUIKitは、iOSアプリの中心的役割を担います。UIKitを深く理解することが、アプリ開発での多くの問題解決に繋がります。本書では、アプリの起動から画面表示、画面レイアウト、イベントハンドリングと、常に稼働しているUIKitの機能を丁寧に解説します。メインとなるコンテンツの表示からステータスバーを含むバーの制御、フォントやテキストの改良など、ビューやテキストの「外観」(アピアランス)を改善する内容も充実させています。使用頻度の高いテーブルビューとコレクションビュー、そしてユニバーサルアプリ化に有益なカスタムコンテナビューコントローラに関しては、チュートリアル形式で解説します。また、StoryboardやAuto Layoutも今後のアプリ開発でさらに重要となる状況を見越して、詳細解説に留まらず同じくチュートリアルで多くの具体例を紹介します。

Amazon詳細ページへImpress詳細ページへ

この記事のキーワード :

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30