25

我正在NSButtonCell为自定义渲染创建自定义。

现在,我想根据鼠标是否在按钮上具有不同的方面。我怎样才能得到这些信息?

谢谢并恭祝安康,

4

7 回答 7

36

这是我为我创造和工作的完美...

第 1 步:创建带有跟踪区域的 Button

 NSButton *myButton = [[NSButton alloc] initWithFrame:NSMakeRect(100, 7, 100, 50)];
[myButton setTitle:@"sample"];

[self.window.contentView addSubview:myButton];
// Insert code here to initialize your application
NSTrackingArea* trackingArea = [[NSTrackingArea alloc]
                                initWithRect:[myButton bounds]
                                options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways
                                owner:self userInfo:nil];
[myButton addTrackingArea:trackingArea];

步骤:2 实现以下方法

- (void)mouseEntered:(NSEvent *)theEvent{
NSLog(@"entered");
[[myButton cell] setBackgroundColor:[NSColor blueColor]];


}

- (void)mouseExited:(NSEvent *)theEvent{
[[myButton cell] setBackgroundColor:[NSColor redColor]];
NSLog(@"exited");

}
于 2014-02-25T18:39:05.477 回答
22

斯威夫特 3:

使用代码创建按钮或仅使用它的@IBOutlet。然后为鼠标悬停(悬停)定义按钮的跟踪区域:

let area = NSTrackingArea.init(rect: yourButtonName.bounds,
                               options: [.mouseEnteredAndExited, .activeAlways], 
                               owner: self, 
                               userInfo: nil)
yourButtonName.addTrackingArea(area)

然后覆盖 mouseEntered 和 mouseExited,在这些函数中设置您想要更改的任何内容(按钮颜色、按钮图像、按钮文本……):

override func mouseEntered(with event: NSEvent) {
    print("Entered: \(event)")
}

override func mouseExited(with event: NSEvent) {
    print("Exited: \(event)")
}

如果您有多个按钮(为每个按钮添加了跟踪区域)并且您需要确定哪个按钮触发了 mouseEntered 事件,您可以为此添加一些 userInfo 信息,而不是:

userInfo: nil

在 userInfo 中为每个按钮添加自定义按钮名称,例如:

userInfo: ["btnName": "yourButtonName"]

然后,您可以在 mouseEntered 和 mouseExited 函数中编写 switch-case 或 if 语句,如下所示:

override func mouseEntered(with event: NSEvent) {
        // Identify which button triggered the mouseEntered event
        if let buttonName = event.trackingArea?.userInfo?.values.first as? String {
            switch (buttonName) {
            case "yourButtonName":
                //do whatever you want for this button..
            case "anotherButtonName":
                //do whatever you want for this button..
            default:
                print("The given button name: \"\(buttonName)\" is unknown!")
            }
        }
    }
于 2017-07-08T13:46:00.323 回答
10

您需要子类化 NSButton 类(甚至更好的 NSButtonCell 类)。正如贾斯汀所说,如果你把这两种方法

- (void)mouseEntered:(NSEvent *)theEvent;
- (void)mouseExited:(NSEvent *)theEvent;

当鼠标进入和退出该区域时,它们应该被调用。您可能还需要重新创建跟踪区域,请看这里:

- (void)updateTrackingAreas

对于淡入和淡出效果,我使用了动画师和 alpha 值,例如:

[self animator]setAlphaValue:0.5]; 
于 2011-05-23T14:52:06.107 回答
4

带有回调的 Swift 5 版本,超级好用:

final class HoverButton: NSButton {

    private let callback: (HoverButton, Bool) -> Void

    init(callback: @escaping (HoverButton, Bool) -> Void) {
        self.callback = callback
        super.init(frame: .zero)
        let area = NSTrackingArea(rect: bounds, options: [.mouseEnteredAndExited, .activeAlways, .inVisibleRect], owner: self, userInfo: nil)
        addTrackingArea(area)
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func mouseEntered(with event: NSEvent) {
        super.mouseEntered(with: event)
        callback(self, true)
    }

    override func mouseExited(with event: NSEvent) {
        super.mouseExited(with: event)
        callback(self, false)
    }

}

用法:

let button = HoverButton { button, isHovered in
    button.animator().alphaValue = isHovered ? 1 : 0.5
}
于 2020-07-21T09:29:14.507 回答
3

一个很好的起点,在 NSResponder 中声明:

- (void)mouseEntered:(NSEvent *)theEvent;
- (void)mouseExited:(NSEvent *)theEvent;

具体来说,纽扣电池的容器(不是电池本身)是 NSResponder。

于 2011-05-23T09:00:28.627 回答
0

对于那些喜欢子类化的人,您也可以自己制作NSButton并在其中分配NSTrackingArea

感谢Joey Zhou,这是一个非常简单而优雅的方法:https ://github.com/Swift-Kit/JZHoverNSButton

它是用Swift 2编写的,但 XCode 会自动在Swift 3 - 4中翻译它而不会出现任何问题。

希望它可以帮助某人

于 2018-07-26T09:11:28.547 回答
0

这是一个简单的代码,用于跟踪某些控件(图像、标签等)上的事件mouse entermouse exit

@IBOutlet weak var myImage: NSImageView!
@IBOutlet weak var myLabel: NSTextField!

override func viewDidLoad() {
    super.viewDidLoad()

    let area1 = myTrakingArea(control: self.myImage)
    let area2 = myTrakingArea(control: self.myLabel)
    self.myImage.addTrackingArea(area1)
    self.myLabel.addTrackingArea(area2)
}

func myTrakingArea(control: NSControl) -> NSTrackingArea {
    return NSTrackingArea.init(rect: control.bounds,
    options: [.mouseEnteredAndExited, .activeAlways],
    owner: control,
    userInfo: nil)
}

override func mouseEntered(with event: NSEvent) {
    if let owner = event.trackingArea?.owner as? NSControl {
        let id : String = owner.identifier!.rawValue

        switch id {
        case self.myLabel.identifier!.rawValue:
                print("Entered Quit Label")
        case self.myImage.identifier!.rawValue:
                print("Entered Quit Image")
            default:
                print("Entered ???")
        }
    }
}

override func mouseExited(with event: NSEvent) {
    if let owner = event.trackingArea?.owner as? NSControl {
        let id : String = owner.identifier!.rawValue

        switch id {
        case self.myLabel.identifier!.rawValue:
                print("Exited Quit Label")
        case self.myImage.identifier!.rawValue:
                print("Exited Quit Image")
            default:
                print("Exited ???")
        }
    }
}
于 2020-02-03T11:11:15.527 回答