1

我是初学者 Cocoa 程序员。我希望在要使用 XCode 4.3.2 for OS X on Lion 开发的程序中,以编程方式将 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 绘图指南重构您的代码,您可能会得到更好的结果。

顺便说一句,你评论

// Draw the text field

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

(*):线程使事情变得复杂,但如果您刚开始使用 Cocoa,这可能无关紧要。

于 2012-04-16T11:22:18.413 回答