フィールドエディターによってテキストを編集する際は、自身のビューの上にフィールドエディターを重ねて設置するため、ユーザーの目に不自然に映らないように、フィールドエディターをセットアップする必要があります。
フィールドエディター、つまりNSTextViewの外見を左右するのは、NSLayoutManager、NSTextContainer、NSTextStorageの3つのオブジェクトです。まずは、これらから設定していきましょう。
NSTextView* fieldEditer; NSLayoutManager* layoutManager = [fieldEditer layoutManager]; [layoutManager setTypesetterBehavior:NSTypesetterBehavior_10_2_WithCompatibility];
レイアウトマネージャに対しては、タイプセッターの動作を設定します。これは、NSTypesetterBehavior_10_2_WithCompatibilityという値を固定的に使用してください。
NSTextView* fieldEditer; NSTextContainer* textContainer = [fieldEditer textContainer]; [textContainer setLineFragmentPadding:0.0]; [textContainer setWidthTracksTextView:NO]; [textContainer setHeightTracksTextView:YES]; [textContainer setContainerSize:NSMakeSize(FLT_MAX, FLT_MAX)];
テキストコンテナに対しては、行頭の余白とコンテナサイズを設定します。行頭の余白は普通に0.0で良いでしょう。コンテナサイズについては、大量に文字を入力されたときに横スクロールするようにするため、縦方向のサイズをテキストビューに追従(実質上の固定)。横方向のサイズを可変とします。
NSTextView* fieldEditer;
NSTextStorage* textStorage = [fieldEditer textStorage];
NSFont* font = [NSFont fontWithName:@"HiraMinPro-W3" size:12.0];
NSDictionary* attribute;
attribute = [NSDictionary dictionaryWithObjectsAndKeys:font,
NSFontAttributeName,
nil];
NSAttributedString* text;
text = [[NSAttributedString alloc] initWithString:string attributes:attribute];
[text autorelease];
[textStorage setAttributedString:text];
テキストストレージに対しては、主にフォントなどの文字属性と、編集する文字列そのものを設定します。
NSLayoutManager、NSTextContainer、NSTextStorageの3つをセットアップすることで、おおまかな設定は完了しましたが、その他にも以下のものを設定する必要があります。
NSTextView* fieldEditer; [fieldEditer setTextColor:[NSColor controlTextColor]]; [fieldEditer setBackgroundColor:[NSColor controlBackgroundColor]]; [fieldEditer setDrawsBackground:YES]; [fieldEditer setTypingAttributes:attribute]; [fieldEditer setEditable:YES]; [fieldEditer setUsesRuler:NO]; [fieldEditer setRichText:NO]; [fieldEditer setImportsGraphics:NO]; [fieldEditer setMinSize:[self bounds]]; [fieldEditer setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)]; [fieldEditer setHorizontallyResizable:YES]; [fieldEditer setVerticallyResizable:YES]; [fieldEditer sizeToFit];
フィールドエディターは、複数のオブジェクトで共有されます。そして、fieldEditor:forObject:やendEditingFor:を呼び出したときも、状態が初期化されることはありません。そのため、他のオブジェクトで設定変更される可能性があるプロパティーは全て設定する必要があります。
また、大量に文字を入力した時に横スクロールするように、ビューのサイズが入力した文字数に応じて可変するようにします。
一通りの設定が終わったところで、フィールドエディターを自身のビュー内に設置します。その際、NSClipViewを併用することで、横スクロールが実現します。
NSClipView* clipview = [[[NSClipView alloc] init] autorelease]; [clipview setCopiesOnScroll:NO]; [clipview setBackgroundColor:[NSColor controlBackgroundColor]]; [clipview setDrawsBackground:YES]; [clipview setFrame:[self textRect]]; [clipview setDocumentView:fieldEditer]; [self addSubview:clipview];
最後に、自身をフィールドエディターのデリゲートに設定し、ファーストレスポンダをフィールドエディターに設定すれば、フィールドエディターの設置が全て完了します。
[fieldEditer setDelegate:self]; [[self window] makeFirstResponder:fieldEditer];
リターンやタブの入力、または他のビューをクリックするなどして、フィールドエディターでの編集が完了するとデリゲートのtextDidEndEditing:メソッドが呼ばれるので、ここに編集結果を自身に反映させて、フィールドエディターを撤去するコードを書きます。
- (void)textDidEndEditing:(NSNotification *)aNotification
{
NSText* fieldEditer = [[self window] fieldEditor:YES forObject:nil];
text = [NSString stringWithString:[fieldEditer string]];
[fieldEditer removeFromSuperview];
[[[self subviews] lastObject] removeFromSuperview];
[fieldEditer setDelegate:nil];
[self setNeedsDisplay:YES];
}
フィールドエディターでの編集結果を自身に取り込むときは、NSTextViewのstringメソッドでテキストを取り出しますが、このオブジェクトは必ずコピーして使います。