1

私は初心者のココアプログラマーです。Lion 上の OS X 用の XCode 4.3.2 で開発されるプログラムのカスタム ビューに描画された幾何学的図の隣に、Cocoa NSTextField (カスタム ビューのサブビュー) をプログラムで配置したいと考えています。私の問題の例を単純にするために、ダイアグラムがテキストフィールドを囲むボックスであるとしましょう (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 単位を追加する必要があると予想していました。

何が起こっている?

4

1 に答える 1

0

ポジショニングを掘り下げることなく、ここで解決する必要があるいくつかの大きな問題があります。Cocoa 描画システムを誤用しています。[box stroke]アプリケーションの任意の場所で(一般的に) 描画を開始することはできません (そうであるように)。グラフィック コンテキストの設定が必要です。

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

あなたのコードがまったく機能していることに少し驚いていますが、適切に定義されたグラフィックス コンテキストがないため、関連する座標系がここにあることを知る方法がありません。描画は基本的にどこかランダムになります。Cocoa Drawing Guideに従ってコードをリファクタリングすると、より良い結果が得られる場合があります。

余談ですが、あなたはコメントします

// Draw the text field

いいえ!テキスト フィールドを描画し ていません。-drawRect:これは、さまざまなビューが呼び出される実行ループの次のターン中に、フレームワークによって行われます。ビュー階層にビューを追加しています。これは些細な違いではありません。いつでもビュー階層を操作できるのは最大 (*) だけです。通常は でのみ描画できます-drawRect:

(*): スレッド化は問題を複雑にしますが、Cocoa を始めたばかりの場合、これはおそらく関係ありません。

于 2012-04-16T11:22:18.413 に答える