我有一个支持图层的NSView。当鼠标进入视图时,我想在鼠标所在的任何地方绘制一个大圆圈。基本上跟踪鼠标位置。不幸的是,圆圈落后于实际的鼠标位置。
我认为它与隐式动画有关。禁用图层“content”属性的动画没有任何效果。
开始编辑:当鼠标移动而圆圈不在鼠标光标后面时,如何在鼠标光标位置绘制圆圈? :结束编辑
这是我的代码。
class TrackingView : NSView
{
override init(frame frameRect: NSRect)
{
super.init(frame: frameRect)
self.wantsLayer = true
}
required init?(coder: NSCoder)
{
super.init(coder: coder)
self.wantsLayer = true
}
//layer backing
override var wantsUpdateLayer : Bool { return true }
override func makeBackingLayer() -> CALayer
{
return TrackingLayer()
}
//tracking areas
override func updateTrackingAreas()
{
//remove current tracking area's
while self.trackingAreas.count > 0
{
self.removeTrackingArea(self.trackingAreas.first as! NSTrackingArea)
}
if let trackingFrames = (self.layer as? TrackingLayer)?.trackingFrames
{
for trackingFrame in trackingFrames
{
let trackingArea = NSTrackingArea(
rect: trackingFrame,
options: NSTrackingAreaOptions.MouseEnteredAndExited | NSTrackingAreaOptions.ActiveInActiveApp | NSTrackingAreaOptions.MouseMoved,
owner: self,
userInfo: nil)
self.addTrackingArea(trackingArea)
}
}
}
//mouse
override func mouseEntered(event: NSEvent)
{
(self.layer as? TrackingLayer)?.userLocation = self.convertPoint(event.locationInWindow, fromView: nil)
}
override func mouseMoved(event: NSEvent)
{
(self.layer as? TrackingLayer)?.userLocation = self.convertPoint(event.locationInWindow, fromView: nil)
}
}
class TrackingLayer : CALayer
{
var trackingFrames : [NSRect] { return [self.frame] }
var userLocation : CGPoint? {
didSet { self.setNeedsDisplay() }
}
override init!()
{
super.init()
self.disableAnimations()
self.backgroundColor = NSColor.whiteColor().CGColor
}
override init!(layer: AnyObject!)
{
super.init(layer: layer)
self.disableAnimations()
}
required init(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
self.disableAnimations()
}
//animations
private func disableAnimations()
{
self.actions = [
"content" : NSNull(),
"sublayers" : NSNull()]
}
//drawing
override func drawInContext(context: CGContext!)
{
if var assumedUserLocation = userLocation
{
CGContextStrokeEllipseInRect(context, CGRectMake(assumedUserLocation.x-5, assumedUserLocation.y-5, 10, 10))
CGContextFillEllipseInRect(context, CGRectMake(assumedUserLocation.x-5, assumedUserLocation.y-5, 10, 10))
}
}
}
答案 0 :(得分:0)
为要进行的更改禁用CALayers动画
CATransaction.withDisabledActions {
hitLayer.move(by: dx, y: dy)
}
extension CATransaction {
class func withDisabledActions<T>(_ body: () throws -> T) rethrows -> T {
CATransaction.begin()
CATransaction.setDisableActions(true)
defer {
CATransaction.commit()
}
return try body()
}
}
也请检查一下,因为这可能更简单
Drawing selection box (rubberbanding, marching ants) in Cocoa, ObjectiveC