可可,ObjectiveC中的绘图选择框(橡皮筋,行进蚂蚁)

Joh*_*ith 12 macos cocoa objective-c nsview

我目前使用鼠标事件实现了一个简单的选择框,并在鼠标拖动时重绘了一个矩形.这是我的代码:

-(void)drawRect:(NSRect)dirtyRect
{
if (!NSEqualRects(self.draggingBox, NSZeroRect))
{
    [[NSColor grayColor] setStroke];
    [[NSBezierPath bezierPathWithRect:self.draggingBox] stroke];
}
}

#pragma mark Mouse Events

- (void)mouseDown:(NSEvent *)theEvent
{
    NSPoint pointInView = [self convertPoint:[theEvent locationInWindow] fromView:nil];
    self.draggingBox = NSMakeRect(pointInView.x, pointInView.y, 0, 0);
    [self setNeedsDisplay:YES];
}

- (void)mouseDragged:(NSEvent *)theEvent
{
    NSPoint pointInView = [self convertPoint:[theEvent locationInWindow] fromView:nil];
    _draggingBox.size.width = pointInView.x - (self.draggingBox.origin.x);
    _draggingBox.size.height = pointInView.y - (self.draggingBox.origin.y);
    [self setNeedsDisplay:YES];
}

- (void)mouseUp:(NSEvent *)theEvent
{
    self.draggingBox = NSZeroRect;
    [self setNeedsDisplay:YES];
}
Run Code Online (Sandbox Code Playgroud)

参考:http://cocoadev.com/HowToCreateWalkingAnts

问题:

这是最有效的方法吗?如果视图很复杂,那么在主视图上绘制透明视图会更有效,而不是在鼠标拖动期间不断重绘视图(http://www.cocoabuilder.com/archive/cocoa/99877- drawing-selection-rectangle.html)?这是怎么做到的?我似乎无法找到任何例子.

Rob*_*Rob 28

如果需要,您可以使用QuartzCore为您设置"行进蚂蚁"的动画.这使您完全脱离了手动绘制橡皮带选择框的世界.您只需定义定义该框的路径,让Core Animation负责绘制框,并为其设置动画.

在XIB的"视图效果"检查器中,打开"核心动画",然后您可以执行以下操作:

#import <QuartzCore/QuartzCore.h>
#import "CustomView.h"

@interface CustomView ()

@property (nonatomic) NSPoint startPoint;
@property (nonatomic, strong) CAShapeLayer *shapeLayer;

@end

@implementation CustomView

#pragma mark Mouse Events

- (void)mouseDown:(NSEvent *)theEvent
{
    self.startPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];

    // create and configure shape layer

    self.shapeLayer = [CAShapeLayer layer];
    self.shapeLayer.lineWidth = 1.0;
    self.shapeLayer.strokeColor = [[NSColor blackColor] CGColor];
    self.shapeLayer.fillColor = [[NSColor clearColor] CGColor];
    self.shapeLayer.lineDashPattern = @[@10, @5];
    [self.layer addSublayer:self.shapeLayer];

    // create animation for the layer

    CABasicAnimation *dashAnimation;
    dashAnimation = [CABasicAnimation animationWithKeyPath:@"lineDashPhase"];
    [dashAnimation setFromValue:@0.0f];
    [dashAnimation setToValue:@15.0f];
    [dashAnimation setDuration:0.75f];
    [dashAnimation setRepeatCount:HUGE_VALF];
    [self.shapeLayer addAnimation:dashAnimation forKey:@"linePhase"];
}

- (void)mouseDragged:(NSEvent *)theEvent
{
    NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];

    // create path for the shape layer

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, self.startPoint.x, self.startPoint.y);
    CGPathAddLineToPoint(path, NULL, self.startPoint.x, point.y);
    CGPathAddLineToPoint(path, NULL, point.x, point.y);
    CGPathAddLineToPoint(path, NULL, point.x, self.startPoint.y);
    CGPathCloseSubpath(path);

    // set the shape layer's path

    self.shapeLayer.path = path;

    CGPathRelease(path);
}

- (void)mouseUp:(NSEvent *)theEvent
{
    [self.shapeLayer removeFromSuperlayer];
    self.shapeLayer = nil;
}

@end
Run Code Online (Sandbox Code Playgroud)

这样,Core Animation就会为您提供行进蚂蚁.

行军蚂蚁演示


Nel*_*aci 6

swift 3版本:

import Cocoa
import QuartzCore

class myView: NSView {

    //MARK:Properties
    var startPoint : NSPoint!
    var shapeLayer : CAShapeLayer!

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
    }


    override func mouseDown(with event: NSEvent) {

        self.startPoint = self.convert(event.locationInWindow, from: nil)

        shapeLayer = CAShapeLayer()
        shapeLayer.lineWidth = 1.0
        shapeLayer.fillColor = NSColor.clear.cgColor
        shapeLayer.strokeColor = NSColor.black.cgColor
        shapeLayer.lineDashPattern = [10,5]
        self.layer?.addSublayer(shapeLayer)

        var dashAnimation = CABasicAnimation()
        dashAnimation = CABasicAnimation(keyPath: "lineDashPhase")
        dashAnimation.duration = 0.75
        dashAnimation.fromValue = 0.0
        dashAnimation.toValue = 15.0
        dashAnimation.repeatCount = .infinity
        shapeLayer.add(dashAnimation, forKey: "linePhase")




    }

    override func mouseDragged(with event: NSEvent) {

        let point : NSPoint = self.convert(event.locationInWindow, from: nil)
        let path = CGMutablePath()
        path.move(to: self.startPoint)
        path.addLine(to: NSPoint(x: self.startPoint.x, y: point.y))
        path.addLine(to: point)
        path.addLine(to: NSPoint(x:point.x,y:self.startPoint.y))
        path.closeSubpath()
        self.shapeLayer.path = path
    }

    override func mouseUp(with event: NSEvent) {
        self.shapeLayer.removeFromSuperlayer()
        self.shapeLayer = nil
    }


}
Run Code Online (Sandbox Code Playgroud)


小智 5

这篇文章有些老,但是我仍然在网上找不到很好的解决方案(框架)。但是我想这是每个人都必须完成的一项任务(内容选择),而且苹果没有提供任何API。但是我创建了自己的框架并将其放在Github上:https : //github.com/ckteebe/MultiSelectionSuiteFramework


Kor*_*and 5

如果有人需要Swift 2.0版本,这里是:

import Cocoa
import QuartzCore


class myView: NSView {

var startPoint : NSPoint!
var shapeLayer : CAShapeLayer!



override func drawRect(dirtyRect: NSRect) {
    super.drawRect(dirtyRect)

    // Drawing code here.
}


override func mouseDown(theEvent: NSEvent) {

    self.startPoint = self.convertPoint(theEvent.locationInWindow, fromView: nil)

    shapeLayer = CAShapeLayer()
    shapeLayer.lineWidth = 1.0
    shapeLayer.fillColor = NSColor.clearColor().CGColor
    shapeLayer.strokeColor = NSColor.blackColor().CGColor
    shapeLayer.lineDashPattern = [10,5]
    self.layer?.addSublayer(shapeLayer)

    var dashAnimation = CABasicAnimation()
    dashAnimation = CABasicAnimation(keyPath: "lineDashPhase")
    dashAnimation.duration = 0.75
    dashAnimation.fromValue = 0.0
    dashAnimation.toValue = 15.0
    dashAnimation.repeatCount = .infinity
    shapeLayer.addAnimation(dashAnimation, forKey: "linePhase")




}

override func mouseDragged(theEvent: NSEvent) {

    let point : NSPoint = self.convertPoint(theEvent.locationInWindow, fromView: nil)
    let path = CGPathCreateMutable()
    CGPathMoveToPoint(path, nil, self.startPoint.x, self.startPoint.y)
    CGPathAddLineToPoint(path, nil, self.startPoint.x, point.y)
    CGPathAddLineToPoint(path, nil, point.x, point.y)
    CGPathAddLineToPoint(path, nil, point.x, self.startPoint.y)
    CGPathCloseSubpath(path)
    self.shapeLayer.path = path
}

override func mouseUp(theEvent: NSEvent) {
    self.shapeLayer.removeFromSuperlayer()
    self.shapeLayer = nil
}



}
Run Code Online (Sandbox Code Playgroud)