Text Kitを使用してUITextViewにリンクを埋め込んだりタブでカラムつけたりする方法

このエントリーをはてなブックマークに追加
はてなブックマーク - Text Kitを使用してUITextViewにリンクを埋め込んだりタブでカラムつけたりする方法

TweetOverview 2.0.2 がリリースされました。
iTunes の App Store で配信中の iPhone、iPod touch、iPad 用 TweetOverview ツイート俯瞰デスクサイドアプリ

TweetOverviewはiOS 7限定でアップデートしたのですが、iOS7限定にして、iOS7の最新機能を出来るだけ取り込むためにそうしました。その一つがTextKitです。「上を目指すプログラマーのためのiPhoneアプリ開発テクニック iOS 7編」を書きました[内容紹介あり] | Zero4Racer PRO Developer’s Blog こちらのリンクにもある、iOS7の解説本を書くためにいろいろテストをした機能を使って作成しています。

どのように使用しているかと言うと、まず、ツイート一覧画面での各ツイートですが、今までは複数のUILabelをレイアウトして、各ツイートのビューを作成していたのですが、最新バージョンでは、ツイートしたユーザー、ツイート時間、ツイートの本文、リツイートしたユーザーなどを一つのUITextViewにして、AttributedTextを設定しています。

ツイート一覧画面
ツイート一覧画面

基本的にはそれぞれの項目の文字サイズなどを設定しているだけなのですが、タブを埋め込んで、時間の部分を右側に固定しているのが、工夫した点です。以下のようなコードで行いました。

段落スタイルNSMutableParagraphStyleのオブジェクトを作成して、そこにタブカラムを付けて、タブカラムの位置を設定しています。
ユーザーアイコンは、普通に左側にedgeInsetを指定しています。本当はexcursionPathを定義して文字が回り込むようにしたかったのですが、paragraphStyleなどと相性が悪く、レイアウトがうまくいきませんでした。

また、詳細画面は、以前は下のツールバー部分にリンク表示ボタン、ユーザー表示ボタン、ハッシュタグ選択ボタンなどを作っていたのですが、iOS7の設計論理である、文字に注意を向ける方針に変更して、画面内のリンク、ハッシュタグ、使用しているアプリなどを直接クリック出来るようにしました。

詳細画面
詳細画面

この際にiOS7で追加されたリンクの埋め込み機能を使用しました。

最初は、UITextViewのリンク検出機能を使っていたのですが、与える文字によって文字検出機能がクラッシュすることがあり、Twitterの提供している、Objective-Cのライブラリを使用しました。
twitter/twitter-text-objc
このライブラリでリンクを検出して、リンクの属性を追加しています。リンクがクリックされた時は、textViewのdelegateに

-(BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange;

が呼び出されるので、そこで @ユーザー なのか、ハッシュタグなのか、リンクなのかを判断して処理をしています。return NOを返すことによって、Safariが呼び出されるのを阻止することが出来ます。

UITextViewには、編集中の処理など、バグらしい挙動も多くありますが、テキストにフォーカスしてシンプルな見た目でも充実した機能を作成するためのたくさんの機能追加がされているので、iOS 7の機能を生かしたアプリが出来ると思います。

12月末に発売されるこちらの本にも、TextKitに関して特集された章が載せられています。是非!

Comments

comments

Powered by Facebook Comments

Post a comment

You may use the following HTML:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">