gpt4 book ai didi

objective-c - 移动 NSView 直到它碰到边界

转载 作者:搜寻专家 更新时间:2023-10-30 19:40:34 26 4
gpt4 key购买 nike

在基于 Cocoa 的应用程序中,我有一个用于绘图的 Canvas ,它继承自 NSView,还有一个矩形,也继承自 NSView。在 Canvas 内部拖动矩形是没有问题的:

-(void)mouseDragged:(NSEvent *)theEvent {
NSPoint myOrigin = self.frame.origin;

[self setFrameOrigin:NSMakePoint(myOrigin.x + [theEvent deltaX],
myOrigin.y - [theEvent deltaY])];
}

像魅力一样工作。我现在遇到的问题:如何防止矩形移出 Canvas ?

所以,首先我想只为左边框修复这个问题,然后调整其他边缘。我的第一个想法是:“检查矩形的 x 原点是否为负数”。但是:一旦它为负,矩形就不能再四处移动(自然地)。我通过将矩形移动到 else 分支中的零 x 偏移来解决这个问题。这行得通,但是……很丑。

所以我对这个有点困惑,有什么提示吗?解决方案绝对是近在咫尺且简单易行。太简单了,我想不出来(一如既往的简单解决方案;)。

问候

苹果电脑

最佳答案

我建议不要使用 deltaXdeltaY;尝试在 superview 中使用事件的位置。您将需要对 subview 的引用。

// In the superview
- (void)mouseDragged:(NSEvent *)event {
NSPoint mousePoint = [self convertPoint:[event locationInWindow]
fromView:nil];

// Could also add the width of the moving rectangle to this check
// to keep any part of it from going outside the superview
mousePoint.x = MAX(0, MIN(mousePoint.x, self.bounds.size.width));
mousePoint.y = MAX(0, MIN(mousePoint.y, self.bounds.size.height));

// position is a custom ivar that indicates the center of the object;
// you could also use frame.origin, but it looks nicer if objects are
// dragged from their centers
myMovingRectangle.position = mousePoint;
[self setNeedsDisplay:YES];
}

您将在 mouseUp: 中执行基本相同的边界检查。

更新:您还应该查看 View 编程指南,它会引导您创建可拖动 View :Creating a Custom View .


应该有用的示例代码,但与您的原始问题并不严格相关:

在 DotView.m 中:

- (void)drawRect:(NSRect)dirtyRect {
// Ignoring dirtyRect for simplicity
[[NSColor colorWithDeviceRed:0.85 green:0.8 blue:0.8 alpha:1] set];
NSRectFill([self bounds]);
// Dot is the custom shape class that can draw itself; see below
// dots is an NSMutableArray containing the shapes
for (Dot *dot in dots) {
[dot draw];
}
}

- (void)mouseDown:(NSEvent *)event {
NSPoint mousePoint = [self convertPoint:[event locationInWindow]
fromView:nil];

currMovingDot = [self clickedDotForPoint:mousePoint];
// Move the dot to the point to indicate that the user has
// successfully "grabbed" it
if( currMovingDot ) currMovingDot.position = mousePoint;
[self setNeedsDisplay:YES];
}

// -mouseDragged: already defined earlier in post

- (void)mouseUp:(NSEvent *)event {
if( !currMovingDot ) return;

NSPoint mousePoint = [self convertPoint:[event locationInWindow]
fromView:nil];
spot.x = MAX(0, MIN(mousePoint.x, self.bounds.size.width));
spot.y = MAX(0, MIN(mousePoint.y, self.bounds.size.height));

currMovingDot.position = mousePoint;
currMovingDot = nil;
[self setNeedsDisplay:YES];
}

- (Dot *)clickedDotForPoint:(NSPoint)point {
// DOT_NUCLEUS_RADIUS is the size of the
// dot's internal "handle"
for( Dot *dot in dots ){
if( (abs(dot.position.x - point.x) <= DOT_NUCLEUS_RADIUS) &&
(abs(dot.position.y - point.y) <= DOT_NUCLEUS_RADIUS)) {
return dot;
}
}
return nil;
}

点.h

#define DOT_NUCLEUS_RADIUS (5)

@interface Dot : NSObject {
NSPoint position;
}

@property (assign) NSPoint position;

- (void)draw;

@end

点.m

#import "Dot.h"

@implementation Dot

@synthesize position;

- (void)draw {
//!!!: Demo only: assume that focus is locked on a view.
NSColor *clr = [NSColor colorWithDeviceRed:0.3
green:0.2
blue:0.8
alpha:1];
// Draw a nice border
NSBezierPath *outerCirc;
outerCirc = [NSBezierPath bezierPathWithOvalInRect:
NSMakeRect(position.x - 23, position.y - 23, 46, 46)];
[clr set];
[outerCirc stroke];
[[clr colorWithAlphaComponent:0.7] set];
[outerCirc fill];
[clr set];
// Draw the "handle"
NSRect nucleusRect = NSMakeRect(position.x - DOT_NUCLEUS_RADIUS,
position.y - DOT_NUCLEUS_RADIUS,
DOT_NUCLEUS_RADIUS * 2,
DOT_NUCLEUS_RADIUS * 2);
[[NSBezierPath bezierPathWithOvalInRect:nucleusRect] fill];
}

@end

如您所见,Dot 类非常轻量级,并使用贝塞尔曲线路径进行绘制。 super View 可以处理用户交互。

关于objective-c - 移动 NSView 直到它碰到边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5744843/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com