テキストを表示、編集するためのユーザインタフェースってのは、PC のもっとも基本的な機能の 1 つだけど、もっともめんどくさいものでもあるんだ。だって、ざっと考えただけでも、インプットメソッドから入力を受けて、コピー、ペーストをして、いろんなフォントを設定して、改行とかページ分割も考えて、横書きもあれば縦書きもあるし、左から書く文字もあれば右から書く文字もあるし、あぁもう大変!
そんなめんどくさいものだけど、いろんなフレームワークが、いろんな手法を提供している。ここでは、もちろん Cocoa のやり方を見てみるよ。
Appliaction Kit では、テキストを取り扱うために 4 つの主要なクラスを提供している。NSTextStorage、NSLayoutManager、NSTextContainer、NSTextView だ。4 つのクラスの関係は、下の図の通り。

NSTextStorage がテキストを保持して、NSTextView がユーザからの操作(キーボードからの入力とか、マウス操作とか)を受け付けるんだ。各クラスの仕事は以下の通りだ。
NSTextStorage
こいつは、テキストそのものを保持しているんだ(つまりテキストのバイトデータ)。実際のところ、NSMutableAttributedString から継承されているクラスだからな。あと、NSLayoutManager への参照を持っていて、テキストが変更されたら通知するんだ。
NSLayoutManager
こいつが実際にテキストを画面に書くんだ。NSTextStorage から文字を取り出して、そいつのグリフを作る。そのグリフを、NSTextContainer の形に従って、NSTextView に書くんだ。
NSTextContainer
これは、テキストが書かれる領域を管理するクラスなんだ。文がどこで改行されるか?とかいうことを取り扱う。あと、サブクラスを作れば、円形にテキストを書いたり、好きな形にテキストを配置することができたりするらしい。
NSTextView
これが、テキストのフロントエンドだ。テキストをユーザに表示して、キーボードやマウスからのイベントを受けるのだ。
NSTextView ってのは、テキストを表示したり、ユーザからの入力を受け付けるためのインタフェース。だから、テキストを追加したりするには、本来なら NSTextStorage を使わないといけない。だけど、めんどくさいといえば、めんどくさいんだよねー。というわけで、NSTextView からテキストを追加するための方法だ。NSTextView の一番最後に文字列を追加する方法を調べよう。
NSTextView は insertText: っていうメソッドを持っている。これは、キーボードから文字を入力した時に使われるメソッドだ。
Application Kit/NSTextView.h
- (void)insertText:(id)insertString;
このメソッドが呼ばれると、今のカーソルの位置に文字列が挿入されるんだ。ということは、カーソルを一番後ろに持っていってから、このメソッドを呼べば、文字列が追加されることになるんだ。
そういう戦略で、コードを。
NSTextViewEx.m (sample)
- (void)appendText:(NSString*)text
{
NSRange wholeRange;
NSRange endRange;
[self selectAll:nil];
wholeRange = [self selectedRange];
endRange = NSMakeRange(wholeRange.length, 0);
[self setSelectedRange:endRange];
[self insertText:text];
}
これは NSTextView にメソッドを追加したものね。まず、selectAll:、selectedRange と呼んでやって文字列全体の長さを得る。そして、長さ 0 で、文字列の一番最後の位置の NSRange を作ってやって、そこを選択する。つまり、カーソルを最後尾に持っていく。で、insertText: を呼んでやればオッケーだ。