2012-04-16 76 views
1

我是初學Cocoa程序員。我希望在程序中定位一個Cocoa NSTextField(自定義視圖的子視圖),旁邊是在自定義視圖上繪製的幾何圖形,該程序將在Lion上用XCode 4.3.2 for OS X開發。爲了讓我的問題簡單易懂,我們假設圖表是包含文本字段的框(除了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

沒有深入定位,有一些更大的問題需要在這裏解決。你濫用Cocoa繪圖系統。您不能(通常)只是在應用程序中的任意位置開始繪製(如[box stroke])。您需要設置圖形環境。

對於繪製到屏幕,您將代碼放在自定義視圖的-drawRect:方法中。框架將確保在調用該方法之前設置適當的上下文,並在之後拆除上下文。

我有點驚訝你的代碼在工作,但由於它沒有明確定義的圖形上下文,所以我們無法知道相關座標系在這裏;繪圖基本上是隨機的。根據Cocoa Drawing Guide重構您的代碼,您可能會得到更好的結果。

順便說一句,你對此有何評論

// Draw the text field

沒有!您不是圖紙的文字欄位;在調用各種視圖'-drawRect:'時,在下一輪運行循環期間由您完成框架。您是將視圖添加到視圖層次結構。這不是一個迂腐的區別:你可以隨時操作最多(*)的視圖層次結構。你一般只能畫-drawRect:

(*):線程複雜化問題,但如果您剛剛開始Cocoa,則這可能不相關。

+0

康拉德,謝謝。儘管我花了一天的時間來試圖理解爲什麼有偏移,但我剛剛注意到,我的觀點被定位在(20,20)窗口中。如果我改變這一點,錯位會相應改變。但是我會按照你的建議來改正整體情況。 – user1336031 2012-04-16 12:02:22

+0

這將在'-drawRect:'中無關,因爲座標系會匹配。 (您很少使用窗口的座標系。)修復整體問題,偏移量將消失。 – 2012-04-16 16:36:25