最近在研究mac客户端上做一个画板功能,首先还是按照iOS开发的经验开始在cocoa
框架中需要相关的或者类似的类,下面简单说说走过的弯路吧
- 首先肯定是要去查
- (void)drawRect:(NSRect)dirtyRect
方法相关的类或者工具类,结果肯定是否定的,因为画板肯定是需要实时绘制,我也了解过display
方法可以更新绘制,但是没有往下深究 - 然后就是
CAShapeLayer
和NSBezierPath
组合,做过iOS的小伙伴们都很熟悉,可是cocoa
框架中我没有找到把NSBezierPath
对象赋值给CAShapeLayer
的属性path
的方法,NSBezierPath
类没有CGPath
属性(UIBezierPath
有这个属性),绝望了 - 最后使用
CAShapeLayer
和CGMutablePathRef
组合,细节请看下文代码
解决:
CAShapeLayer
和CGMutablePathRef
组合
- 创建一个集成自
NSView
的类 -
.h
文件没有内容就不贴了,直接上.m
文件
#import "SHSettingTestView.h"
#import <QuartzCore/QuartzCore.h>
@interface SHSettingTestView ()
@property (nonatomic , strong) CAShapeLayer *shapeLayer;
@property (nonatomic) CGMutablePathRef path;
@end
@implementation SHSettingTestView
- (instancetype)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.wantsLayer = YES;
self.layer.backgroundColor = NSColor.whiteColor.CGColor;
}
return self;
}
- (BOOL)mouseDownCanMoveWindow
{
[super mouseDownCanMoveWindow];
return NO;
}
- (void)updateTrackingAreas
{
NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:(NSTrackingEnabledDuringMouseDrag|NSTrackingActiveInActiveApp|NSTrackingInVisibleRect|NSTrackingAssumeInside|NSTrackingCursorUpdate)owner:self userInfo:nil];
[self addTrackingArea:trackingArea];
}
- (void)mouseDown:(NSEvent *)event
{
CGPathMoveToPoint(self.path, nil, event.locationInWindow.x, event.locationInWindow.y);
self.shapeLayer.path = self.path;
}
- (void)mouseDragged:(NSEvent *)event
{
CGPathAddLineToPoint(self.path, nil, event.locationInWindow.x, event.locationInWindow.y);
self.shapeLayer.path = self.path;
}
#pragma mark - lazy
- (CAShapeLayer *)shapeLayer
{
if (!_shapeLayer) {
_shapeLayer = [CAShapeLayer layer];
_shapeLayer.frame = self.bounds;
_shapeLayer.fillColor = [NSColor clearColor].CGColor;
_shapeLayer.lineWidth = 1.0;
_shapeLayer.lineCap = kCALineCapRound;
_shapeLayer.lineJoin = kCALineJoinRound;
_shapeLayer.strokeColor = NSColor.blueColor.CGColor;
[self.layer addSublayer:_shapeLayer];
}
return _shapeLayer;
}
- (CGMutablePathRef)path
{
if (!_path) {
_path = CGPathCreateMutable();
}
return _path;
}
@end
-
updateTrackingAreas
方法之前写过文章传送门 -
mouseDownCanMoveWindow
该方法防治穿透导致点击事件冲突
完成
网友评论