简体   繁体   中英

OSX CustomView Doesn't Work After Window Resize

I have a simple view that displays an NSBezierpath. On mouseDown inside the path, the path's fill color sets to yellow and the view redraws. On mouseDown outside the path, the path's fill color sets to blue and the view redraws.

In my storyboard, I have a single window controller with a window content segue to a view controller. The view, customview class HeartView (below) fills the entire view controller.

Everything works fine until the user resizes the window vertically. After that, the view exhibits bizarre behavior: mouseDown no longer works everywhere inside the path, the recolor sometimes happens on mouseDown outside the path, and the path sometimes (but not always) doesn't completely fill. I think something is going on in the superview, but I don't know what.

    import Cocoa

    class HeartView: NSView {

        var mouseLocation : NSPoint = NSZeroPoint

        func drawObject(){
            //Create an empty Bezier path
            let aBezier : NSBezierPath = NSBezierPath()
            aBezier.moveToPoint(CGPoint(x: 176.95,y: 44.90))
            aBezier.curveToPoint(CGPoint(x: 166.71,y: 145.89),
                controlPoint1: CGPoint(x: 76.63,y: 76.78),
                controlPoint2: CGPoint(x: 82.59,y: 206.70))
            aBezier.curveToPoint(CGPoint(x: 176.95,y: 44.90),
                controlPoint1: CGPoint(x: 237.55,y: 224.76),
                controlPoint2: CGPoint(x: 276.83,y: 95.98))
            aBezier.closePath()
                    if (aBezier.containsPoint(NSMakePoint(mouseLocation.x, mouseLocation.y))){
                        NSColor.yellowColor().setFill()
                        NSColor.greenColor().setStroke()        
                    } else {
                        NSColor.blueColor().setFill()
                        NSColor.orangeColor().setStroke()
                    }
                    aBezier.fill()
                    aBezier.lineWidth = 2.0
                    aBezier.stroke()
         }

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

        override func mouseDown(theEvent: NSEvent) {
            mouseLocation.x = theEvent.locationInWindow.x
            mouseLocation.y = theEvent.locationInWindow.y
            self.setNeedsDisplayInRect(self.frame)  
        }

}

I found the answer in Lucas Derraugh's video on Mouse Events (Cocoa Programming L27). Turns out, I was capturing the mouseDown event in the superview's coordinate system. In the mouseDown event, I used "locationInWindow," which is what caused the strange behavior. I changed the method to:

    override func mouseDown(theEvent: NSEvent) {
         var viewPoint:NSPoint = self.convertPoint(theEvent.locationInWindow, fromView: nil)
         mouseLocation.x = viewPoint.x
         mouseLocation.y = viewPoint.y
         self.needsDisplay = true
} 

to convert from the window's coordinate system to the view's. Things now work well after any window resize event.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM