子类化NSControl,在Swift

时间:2016-08-04 23:29:21

标签: swift macos subclass ibaction nscontrol

我已经子类化了一个NSSlider,无论是否按下了选项键,它的行为都不同。为了做到这一点,我重写了mouseDown func。它似乎做了这个工作。 问题是,我注意到我的ViewController中连接的@IBAction仅在未按下选项键时触发(即当mouseDown方法传递给super时)。为了让@IBAction能够执行,我缺少什么?

非常感谢 除了这个问题,欢迎对代码的改进建议......: - )

乔什

class ViewController: NSViewController {

    @IBOutlet weak var theSlider: MySlider!
    @IBAction func moveSlider(sender: NSSlider) {
        print(sender.floatValue) //works only with optionKey unpressed
    }
}

class MySlider: NSSlider { //Implemented in another source file

    @IBInspectable var multiplier: Float = 0.5
    private var modifierKeys = NSEventModifierFlags.AlternateKeyMask
    private var optionKeyPressed = false
    private var previousSliderPosition: Float = 0.0

//MARK: Init with NSCoder
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        Swift.print("init Coder called")

        self.continuous = true
        NSEvent.addLocalMonitorForEventsMatchingMask(.FlagsChangedMask) { (theEvent) -> NSEvent? in
            self.flagsChanged(theEvent)
            return theEvent
        }
    }

//MARK: Mouse tracking
    override func mouseDown(theEvent: NSEvent) {

        if optionKeyPressed {

            var keepOn = true
            previousSliderPosition = self.floatValue * Float(self.bounds.width) / Float(self.maxValue)

            while keepOn {
                if let nextEvent = self.window?.nextEventMatchingMask(Int(NSEventMask.LeftMouseUpMask.rawValue) | Int(NSEventMask.LeftMouseDraggedMask.rawValue))
                {
                    switch nextEvent.type
                    {
                    case .LeftMouseDragged:
                         let mouseInnerLocationX = Float(self.convertPoint(nextEvent.locationInWindow, fromView: self.superview).x)
                        let mouseDelta = mouseInnerLocationX - previousSliderPosition
                        let newSliderPosition = previousSliderPosition + (mouseDelta) * multiplier

                        self.floatValue = newSliderPosition * Float(self.maxValue) / Float(self.bounds.width)
                        break

                    case .LeftMouseUp:
                        keepOn = false
                        break

                    default:
                        break
                    }
                }
            }
        } else {
            super.mouseDown(theEvent)
        }
    }

//MARK: Option key handling
    override func flagsChanged(theEvent: NSEvent) {
        if (theEvent.modifierFlags.rawValue & NSEventModifierFlags.DeviceIndependentModifierFlagsMask.rawValue) == NSEventModifierFlags.AlternateKeyMask.rawValue {
            optionKeyPressed = true
        } else {
            optionKeyPressed = false
        }
    }
}

1 个答案:

答案 0 :(得分:2)

如果您未拨打super.mouseDown,则需要自行发送操作:

sendAction(action, to: target)

sendAction(_:to:)actiontargetNSControl的现有成员。