有关NSRect的问题......在Hillegass一书中,我们正在创建一个NSRect,我们正在绘制一个椭圆形(NSBezierPath *)。根据我们视图中的鼠标按下并随后拖动的位置,NSRect的size.width和/或size.height可能是负的(即如果我们从右上角开始,向左下方拖动 - 两者都是负数)。实际绘制时,系统是否使用我们的负宽度和/或高度来定位我们拖动的NSPoint?这样更新NSRect?如果我们需要NSRect的大小,我们应该只使用绝对值吗?
在本章中,作者使用MIN()和MAX()宏来创建NSRect。但是,在挑战解决方案中,他们提供这三种方法来响应鼠标事件:
- (void)mouseDown:(NSEvent *)theEvent
{
NSPoint pointInView = [self convertPoint:[theEvent locationInWindow] fromView:nil];
// Why do we offset by 0.5? Because lines drawn exactly on the .0 will end up spread over two pixels.
workingOval = NSMakeRect(pointInView.x + 0.5, pointInView.y + 0.5, 0, 0);
[self setNeedsDisplay:YES];
}
- (void)mouseDragged:(NSEvent *)theEvent
{
NSPoint pointInView = [self convertPoint:[theEvent locationInWindow] fromView:nil];
workingOval.size.width = pointInView.x - (workingOval.origin.x - 0.5);
workingOval.size.height = pointInView.y - (workingOval.origin.y - 0.5);
[self setNeedsDisplay:YES];
}
- (void)mouseUp:(NSEvent *)theEvent
{
[[self document] addOvalWithRect:workingOval];
workingOval = NSZeroRect; // zero rect indicates we are not presently drawing
[self setNeedsDisplay:YES];
}
无论潜在的负值如何,此代码都会生成一个成功的矩形。我知道负值只反映了相对于原点的左移(我们“鼠标击落”的点)。在正确计算我们拖动的NSPoint后,幕后发生了什么?
答案 0 :(得分:1)
NSRect刚刚被定义为NSPoint和NSSize。 NSSize只是被定义为一对CGFloats,但文档说:
通常,宽度和高度的值都是非负的。创建NSSize结构的函数不会阻止您为这些属性设置负值。但是,如果宽度或高度的值为负,则某些方法的行为可能未定义。
在上面显示的代码中,幕后没有任何花哨的东西。你正在创建一个矩形(workingOval),它恰好具有负的大小或宽度,而你实际上并没有在任何地方使用它。
根据您在其他地方使用workOval所做的事情,幕后发生的事情会有所不同。但它将是三个非常简单的事情之一。有些方法将rect(origin =(30,40),size =( - 10,-20))视为与(origin =(20,20),size =(10,20))相同;其他人将其视为无效的矩形;有些人假设他们没有测试,只是给你垃圾结果。例如,NSMinX将返回30而不是10。