我是初学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单位。
发生了什么事?
答案 0 :(得分:0)
如果不钻研定位,这里需要解决一些更大的问题。你在滥用Cocoa绘图系统。您(通常)不能在应用程序中的任何随机位置开始绘制(如[box stroke]
所做的那样)。您需要设置图形上下文。
要绘制到屏幕,请将代码放在自定义视图的-drawRect:
方法中。框架将确保在调用该方法之前设置适当的上下文,并在之后拆除上下文。
我对你的代码工作有点惊讶,但因为它没有明确定义的图形上下文,所以我们无法知道相关的坐标系是什么;绘图基本上是随机的。根据{{3}}重构您的代码,您可能会获得更好的结果。
顺便说一句,你发表评论
// Draw the text field
不!您不是绘图文本字段;这是在调用各种视图'-drawRect:
时,在下一轮运行循环期间由框架完成的。您正在向视图层次结构中添加视图。这不是一个迂腐的差异:您可以随时操纵视图层次结构(*)。您通常只能在-drawRect:
中绘制。
(*):线程使问题变得复杂,但如果你刚刚开始使用Cocoa,这可能就不那么重要了。