Geometry 関数
NSBundle
NSDictionary
NSFileManager
NSMutableAttributedString
NSNumber
NSScanner
NSString
NSTimer
Graphic 関数
NSApplication
NSBezierPath
NSCell
NSColor
NSCursor
NSCustomImageRep
NSDocument
NSDocumentController
NSDragging
NSEvent
NSFontManager
NSGraphicsContext
NSImage
NSMenu
NSOutlineView
NSPanel
NSPopUpButton
NSResponder
NSScrollView
NSString 追加
NSTableColumn
NSTableView
NSTextStorage
-NSTextStorage とは
-NSTextStorage をプログラムから変更する
-テキストが編集された通知を受け取る
NSTextView
NSToolbar
NSView
NSWindow
NSWorkspace
その他
.nib ウィンドウ
Views パレット
クラス
インスタンス変数
メソッド
CFXML
Carbon Event
Carbon Graphics
Cocoa で日本語
メソッド
その他

- Application Kit-
NSTextStorage

Application Kit - NSTextStorage
NSTextStorage とは
Keywords: NSTextStorage, text handling

NSTextStorage ってのは、NSTextView を使ってテキストを取り扱うときに使われるクラスなんだ。主な役目は次の通り:

  • テキストを保持する
    NSTextStorage が実際のテキストデータを保持するんだ。このクラスは NSMutableAttributedString を継承してるクラスだから、そっからも分かるよな。
  • NSLayoutManager の参照を保持する
    テキスト編集クラスの次の階層である、NSLayoutManager への参照を持っているんだ。複数持つことができるよ。
  • テキストの変更を受け取る、通知する
    ユーザが NSTextView に文字を打ち込んだりすると、その編集情報がこのクラスまでやってくるんだ。それを取り扱う。あと delegate にそのイベントを通知したりするんだ。

Application Kit - NSTextStorage
NSTextStorage をプログラムから変更する
Keywords: beginEditing, endEditing

NSTextStorage が保持しているテキストを、プログラムの内部で変更することを考えてみよう。実際には、文字を変更するメソッドが定義されているのは NSTextStorage ではなくて、その親クラスの NSMutableAttributedString だ。NSMutableAttributedString にある、文字変更メソッドや、属性変更のためのメソッドを使うんだ。

1 つ気をつけてほしいのは、beginEditingendEditing を使うと、もっと効率的に編集が行われる、っていうこと。

Application Kit/NSTextStorage.h
- (void)beginEditing;
- (void)endEditing;

NSTextStorage ではテキストが変更されたら、NSTextLayout を呼んで、NSTextView の画面の表示を変更しないといけない。でも、毎回やってたら遅くなるわな。それをコントロールすることができるんだ。

テキストを変更する前に、beginEditing を呼んでおく。そうすると、その後の変更はとりあえずバッファに突っ込まれて、まだ NSTextLayout に通知されないんだ。変更が終わったら endEditing を呼ぶ。その時点で、NSTextStorage は変更を処理して、上のレイヤに通知するんだ。そこんとこ注意。


Application Kit - NSTextStorage
テキストが編集された通知を受け取る
Keywords: NSTextStorageDelegate

NSTextView を使ってテキストを編集すると、編集の情報が階層を伝って NSTextStorage までやってくるんだ。NSTextStorage はそれをもとに、自分が持っているテキストデータを変更する。そのイベントを delegate が受け取ることができるんだ。

NSTextStorage は、テキストを変更するときに次の 2 つのメッセージを投げる。

Application Kit/NSTextStorage.h
- (void)textStorageWillProcessEditing:(NSNotification *)notification;
- (void)textStorageDidProcessEditing:(NSNotification *)notification;

当然、変更前が textStorageWillProcessEditing: で、後が textStorageDidProcessEditing: だな。これで、テキスト変更のイベントを受け取ることができるぜ。

じゃ、次の質問。どこが変更されたかを知るには?それには NSTextStorage の次のメソッドを使う。

Application Kit/NSTextStorage.h
- (unsigned int)editedMask;
- (NSRange)editedRange;
- (int)changeInLength;

editedMask は、何が変更されたかを調べる。属性か?文字か?その両方か?editedRange は、変更された範囲。changeInLength は何文字が変更されたかだ。文字が挿入されたときはプラスの値。削除されたときはマイナスの値だ。

では、サンプルを見てみよう。

MyDocument.m (sample)
- (void)textStorageDidProcessEditing:(NSNotification*)notification
{
    NSTextStorage* textStorage = [_textView textStorage];
    
    unsigned int mask = [textStorage editedMask];
    NSRange range = [textStorage editedRange];
    int length = [textStorage changeInLength];
    
    if (mask & NSTextStorageEditedAttributes) {
        NSLog(@"Edited mask: NSTextStorageEditedAttributes");
    }
    if (mask & NSTextStorageEditedCharacters) {
        NSLog(@"Edited mask: NSTextStorageEditedCharacters");
    }
    
    NSLog(@"Edited range: location=%d, length=%d", 
            range.location, range.length);
    
    NSLog(@"Change in length: %d", length);
}

ここでは textStorageDidProcessEditing: の中で、編集情報を表示させている。プログラムを走らせて、テキストビューに文字を打ち込む度に、このメソッドが呼び出されるのが確認できるはずだよ。

■サンプルダウンロード:
TextStorageDelegate.tar.gz



[Home] [Download] [Archives] [BBS] [Cocoa Programming Tips 1001] [Core Foundation の秘密] [Safari Developer Center] [はじめてのブラウザのつくり方] [Sketch BP] [スクリーンセイバーを作ろう] [Objective-C 最適化] [Authorization API 完全理解] [Mac OS X Programming Books Review] [オブジェクト指向の言語比較論] [panther-dev]

mailto: mkino@xd5.so-net.ne.jp