我无法在NSBezierPath绘制的图表中正确定位NSTextField

时间:2012-04-16 10:51:09

标签: macos cocoa nsview nstextfield nsbezierpath

我是初学Cocoa程序员。我希望以编程方式将Cocoa NSTextField(自定义视图的子视图)放在一个程序中的自定义视图上绘制的几何图旁边,该程序将使用XCode 4.3.2 for Lion X上的OS X进行开发。为了使我的问题的例子简单,让我们说图是一个包围文本字段的框(除了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单位。

发生了什么事?

1 个答案:

答案 0 :(得分:0)

如果不钻研定位,这里需要解决一些更大的问题。你在滥用Cocoa绘图系统。您(通常)不能在应用程序中的任何随机位置开始绘制(如[box stroke]所做的那样)。您需要设置图形上下文。

要绘制到屏幕,请将代码放在自定义视图的-drawRect:方法中。框架将确保在调用该方法之前设置适当的上下文,并在之后拆除上下文。

我对你的代码工作有点惊讶,但因为它没有明确定义的图形上下文,所以我们无法知道相关的坐标系是什么;绘图基本上是随机的。根据{{​​3}}重构您的代码,您可能会获得更好的结果。

顺便说一句,你发表评论

// Draw the text field

不!您不是绘图文本字段;这是在调用各种视图'-drawRect:时,在下一轮运行循环期间由框架完成的。您正在向视图层次结构中添加视图。这不是一个迂腐的差异:您可以随时操纵视图层次结构(*)。您通常只能在-drawRect:中绘制。

(*):线程使问题变得复杂,但如果你刚刚开始使用Cocoa,这可能就不那么重要了。