【问题标题】:I'm unable to position NSTextField correctly in NSBezierPath-drawn diagram我无法在 NSBezierPath 绘制的图中正确定位 NSTextField
【发布时间】:2012-04-27 16:48:15
【问题描述】:

我是一个初学者 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 个单位。

发生了什么事?

【问题讨论】:

    标签: macos cocoa nsview nstextfield nsbezierpath


    【解决方案1】:

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

    为了在屏幕上绘图,您将代码放入自定义视图的-drawRect: 方法中。框架将确保在调用该方法之前设置适当的上下文,然后将删除上下文。

    我有点惊讶你的代码能正常工作,但因为它没有明确定义的图形上下文,所以我们无法知道相关坐标系在这里;绘图基本上是随机的。按照Cocoa Drawing Guide重构你的代码,你可能会得到更好的结果。

    顺便说一句,你评论

    // Draw the text field

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

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

    【讨论】:

    • 康拉德,谢谢。虽然我花了一天时间试图理解为什么我有偏移,但我刚刚注意到我的视图位于窗口中的 (20, 20) 处。如果我改变它,错位也会相应改变。但我会按照你的建议进行整体纠正。
    • 这与-drawRect: 无关,因为坐标系会匹配。 (你很少使用窗口的坐标系。)修复整体问题,偏移就会消失。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    相关资源
    最近更新 更多