2012-04-16 7 views
1

私は初心者のCocoaプログラマです。私はCocoa NSTextField(カスタムビューのサブビュー)を、プログラムでカスタムビューに描画された幾何学図の横にプログラム的に配置して、XCode 4.3.2 for Lionで開発することを希望します。私の問題の例を単純にするために、ダイアグラムがテキストフィールドを囲むボックスになっているとしましょう(NSTextFieldで利用可能なベゼルまたはボーダーに加えて、実際には私のダイアグラムはもっと複雑になります)。私はテキストフィールドとボックスが私の期待どおりに整列していないことが分かります(下記のサンプルコードを参照)。どうして?NSBezierPathの描画図でNSTextFieldを正しく配置できません

単純な非ドキュメントベースのプロジェクトを診断例として作成しました。この例では、カスタムビューをアプリケーションウィンドウにドラッグし、下のコードを追加してIBOutletからビューに接続しました:

AnAppDelegate.h:

#import <Cocoa/Cocoa.h> 

@interface AnAppDelegate : NSObject <NSApplicationDelegate> { 
    IBOutlet NSView *view; 
    NSRect textFieldRect; 
    NSTextField *textField; 
    NSBezierPath *box; 
} 

@property (assign) IBOutlet NSWindow *window; 

@end 

AnAppDelegate.m:このプログラムが実行されると

#import "AnAppDelegate.h" 

@implementation AnAppDelegate 

@synthesize window = _window; 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    textFieldRect = NSMakeRect(100, 100, 100, 20); 
    textField = [[NSTextField alloc] initWithFrame:textFieldRect]; 

    NSRect frame = [textField frame]; 
    NSLog(@"frame %f %f %f %f", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); 

    NSRect bounds = [textField bounds]; 
    NSLog(@"bounds %f %f %f %f", bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); 

    // Draw the text field 
    [textField setStringValue:@"My text field"]; 
    [textField setBezeled:YES]; 
    [textField setDrawsBackground:NO]; 
    [textField setEditable:YES]; 
    [textField setSelectable:YES]; 
    [view addSubview:textField]; 

    // Draw a box (rectangle) around the text field 
    //NSRect boxRect = [textField frame]; 
    box = [[NSBezierPath alloc] init]; 
    //boxRect.origin.x += 10; 
    //boxRect.origin.y += 10; 
    //boxRect.size.width += 20; 
    //boxRect.size.height += 20; 
    [box appendBezierPathWithRect:[textField frame]]; // :boxRect]; 
    [box stroke]; 

} 

@end 

、ボックスがずれ左にし、下に表示されます各ディメンションのテキストフィールドの高さによって表示されます。私はそれがNSTextFieldのサブビューの下に現れ、それによって隠されることを期待しています。 (生産プログラムではあまり意味がありません)

ここで、上記のソースのコメントアウトされた行のコメントを外すと、枠の代わりにboxRectが追加されますテキストボックスから10単位分、私のボックスが最初に表示されますが、+10単位ではなく-10単位を元に追加する必要があるはずです。

何が起こっていますか?

答えて

0

ここで解決しなければならない大きな問題がいくつかあります。あなたはココア製図システムを悪用しています。あなたのアプリケーションの任意の場所で描画を開始することはできません([box stroke])。グラフィックスコンテキストを設定する必要があります。

画面に描画する場合は、コードをカスタムビューの-drawRect:メソッドに置きます。フレームワークは、そのメソッドを呼び出す前に適切なコンテキストを設定し、後でコンテキストを破棄します。

あなたのコードはまったく動作していますが、そこには明確なグラフィックスコンテキストはありませんので、関連する座標系が何であるかを知る方法がありません。抽選は基本的にどこかでランダムに行われます。 Cocoa Drawing Guideに従ってコードをリファクタリングすると、より良い結果が得られる場合があります。余談として

、あなたはありません

// Draw the text field

をコメント!あなたはではありません。テキストフィールド。さまざまなビュー '-drawRect:が呼び出されたときに、実行ループの次のターンであなたのためのフレームワークによって行われます。ビュー階層にビューを追加するのはです。これは賢明な違いではありません。いつでも最大で(*)ビュー階層を操作できます。一般的には-drawRect:にしか描画できません。

(*):スレッディングは問題を複雑にしますが、これはCocoaをちょうど開始したばかりの場合は関係ありません。

+0

コンラッド、ありがとう。なぜ私はオフセットがあるのか​​を理解しようとしていましたが、私の見解はウィンドウ内で(20,20)に位置していることに気がつきました。私がそれを変えれば、それに応じてミスアライメントも変わります。しかし、あなたが提案したように全体的に修正します。 – user1336031

+0

'-drawRect:'では座標系が一致するので、これは無関係です。 (あなたはほとんどウィンドウの座標系を使用しません)全体的な問題を修正すると、オフセットが消えます。 –

関連する問題