NSTableViewのUIを改良する、その2

一歩後退して、NSTextField周りを調べたのでメモる。

NSTextFieldの描画領域のマージン

NSTextFieldの描画領域boundsと[NSAttributedString boundingRectWithSize:options:context]が返す描画領域は一致しない。 NSAttributedStringの描画領域と一致するのは、[NSCell drawingRectForBounds:]の値の方。

[NSCell drawingRectForBounds:]は、NSControl中のNSCellの描画領域を計算するメソッド。

おそらく、ControlとCellの差は、フォーカスリング分の差と思われる。

テキストの分量に応じて、NSTextFieldの描画サイズを可変にするときに、上記のControlとCellの差を考慮に入れて計算する必要がある。

詳しくはソースコードの[NSTextField interSpacing]と[NSTextField calcBoundingHeightWithFixedCurrentWidth]を参照すること。

NSTextField間の移動をカーソルキーで行う

[NSTextFieldDelegate control:textView: doCommandBySelector:]に記述するのは基本。

左右の矢印キーを押すと、”moveRight:”や”moveLeft:”のセレクタが来る。

この時に、キャレットが文末や文頭にあった場合にnextKeyViewやpreviousKeyViewにフォーカスを移動する。 これだけだと、フォーカスが移動しツァキのNSTextFieldのテキストが、全て選択されてしまう。

以下のように、currentEditorにmoveToEndOfDocument:を投げることで移動先のキャレットを移動すると良い。

NSTextField* theTextFiled = (NSTextField*)control.previousKeyView;

[theTextFiled becomeFirstResponder];
[theTextFiled.currentEditor moveToEndOfDocument:nil];

キャレット位置の判定や移動方法はソースコードを参照のこと。

現状のソースコードの欠点は、キャレットの縦方向移動開始時にX軸の値を保存していないため、NSTextField間の移動時後にキャレットのX軸がズレることがある。

ソースコードはここ。( TextClassTester.zip )