子视图的错误定位

时间:2011-10-22 22:25:47

标签: objective-c cocoa positioning nsview

我想一个接一个地安排几个自定义NSView。 但是当我运行应用程序时,视图使用不同的(加倍的)帧原点值绘制,而不是代码中设置的值。

以下是包含2个视图的简化代码:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application 

float height1 = 40.0;
float height2 = 65.0;

float width = [[window contentView] frame].size.width;

NSRect r1 = NSMakeRect(0, 0, width, height1);
NSRect r2 = NSMakeRect(0, height1, width, height2);

MyView *c1 = [[MyView alloc] initWithFrame:r1];
MyView *c2 = [[MyView alloc] initWithFrame:r2];

[[window contentView] addSubview:c1];
[[window contentView] addSubview:c2];
}

MyView的代码基本上只来自drawRect:

- (void)drawRect:(NSRect)dirtyRect {
// Drawing code here.

NSRect cellFrame = [self frame];

// frame Y coordinates at superview
float superY = [self convertPoint:[self frame].origin 
                      toView:[self superview]].y;

NSLog(@"superY:%f selfY:%f", superY, cellFrame.origin.y);


// top, bottom border and diagonal line of [self frame]
NSBezierPath* borderLine = [NSBezierPath bezierPath];

NSPoint pt1 = NSMakePoint(cellFrame.origin.x, 
                          cellFrame.origin.y);
NSPoint pt2 = NSMakePoint(cellFrame.origin.x + cellFrame.size.width,
                          cellFrame.origin.y);
NSPoint pt3 = NSMakePoint(cellFrame.origin.x,
                          cellFrame.origin.y + cellFrame.size.height);
NSPoint pt4 = NSMakePoint(cellFrame.origin.x + cellFrame.size.width,
                          cellFrame.origin.y + cellFrame.size.height);

[borderLine moveToPoint:pt1];
[borderLine lineToPoint:pt2];
[borderLine lineToPoint:pt3];
[borderLine lineToPoint:pt4];

[[NSColor redColor] setStroke];
[borderLine setLineWidth:01];
[borderLine stroke];
} 

这是结果(如你所见 - 第二个视图的'y'坐标加倍,由于某种原因,这个视图只是部分绘制):

result with console

1 个答案:

答案 0 :(得分:1)

您正在混淆视图框架和边界矩形的概念。 “界限”是指视图在其自身坐标系中的尺寸,即原点为零,尺寸为视图的宽度和高度。

“框架”是指视图在其父视图坐标系中的尺寸,即原点将位于视图在其超视图中的位置,宽度和高度将与边界矩形相同。

因此,对于您的示例代码中的日志记录,您不必要地错误地调用“convertPoint”,因为只需调用“[self frame] .origin”即可获得视图的实际来源

进行绘图时,需要调用“[self bounds]”来获取要绘制的矩形。在您的代码中,您调用“[self frame]”,它在superview的坐标系(框架)中为您提供一个矩形,但这不起作用,因为绘图例程在视图的自己的(边界)坐标系中绘制(即有原点)在{0,0}}

如果视图填充了其超级视图的整个内容,则会出现例外情况,在这种情况下,您可以调用[self bounds]或[self frame],因为两者都会返回相同的矩形。

我通过更改

让您的代码正常工作

NSRect cellFrame = [self frame];

NSRect cellFrame = [self bounds];

此外,记录NSRect的最简单方法是

例如

NSLog(@"%@", NSStringFromRect([self frame]));

希望有所帮助。