2012-04-16 75 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