NSButton 上的简单鼠标悬停效果

发布于 2024-11-09 17:47:39 字数 115 浏览 0 评论 0原文

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

现在,我想要有不同的方面,具体取决于鼠标是否位于按钮上。我怎样才能得到这些信息?

谢谢和问候,

I am creating a custom NSButtonCell for a custom rendering.

Now, I want to have different aspect depending if the mouse is over the button or not. How can I get this information?

Thanks and regards,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

胡渣熟男 2024-11-16 17:47:39

这是我完美创建并为我工作的...

步骤 1:创建带有跟踪区域的按钮

 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");

}

Here is i have created and worked for me perfectly...

Step 1: Create the Button with tracking area

 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];

Step: 2 Implement the following methods

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


}

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

}
じ违心 2024-11-16 17:47:39

Swift 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"]

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

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!")
            }
        }
    }

Swift 3:

Create the button with code or just use it's @IBOutlet.
Then define the button's tracking area for mouse over (hover):

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

Then override mouseEntered and mouseExited, set whatever you want to change (button color, button image, button text,..) in these functions:

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

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

If you have multiple buttons (with tracking area added for each) and you need to identify which button triggered the mouseEntered event, you can add some userInfo information for this purpose, so instead of:

userInfo: nil

Add your custom button name in userInfo for each button, for example:

userInfo: ["btnName": "yourButtonName"]

Then you can write a switch-case or if statements in your mouseEntered and mouseExited functions like this:

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!")
            }
        }
    }
吐个泡泡 2024-11-16 17:47:39

您需要子类化 NSButton 类(或者更好的是 NSButtonCell 类)。
正如贾斯汀所说,如果你放置这两个方法,

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

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

- (void)updateTrackingAreas

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

[self animator]setAlphaValue:0.5]; 

You need to Subclass the NSButton class (or even better the NSButtonCell class).
As Justin said if you put the two method

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

They should get called when the mouse enter and exit the area. You may also need to re create the tracking area, look here:

- (void)updateTrackingAreas

For fade in and fade out effect I played with animator and alpha value for example:

[self animator]setAlphaValue:0.5]; 
对风讲故事 2024-11-16 17:47:39

带回调的 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: .zero, 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
}

Swift 5 version with callback, super easy to use:

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: .zero, 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)
    }

}

Usage:

let button = HoverButton { button, isHovered in
    button.animator().alphaValue = isHovered ? 1 : 0.5
}
南风起 2024-11-16 17:47:39

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

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

具体来说,按钮单元格的容器(不是单元格本身)是 NSResponder。

a good starting point, declared in NSResponder:

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

specifically, the button cell's container (not the cell itself) is the NSResponder.

尘曦 2024-11-16 17:47:39

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

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

它是用 Swift 2 编写的,但 XCode 会自动将其翻译为 Swift 3 - 4,无需任何操作问题。

希望它可以帮助别人

For those who prefer subclassing, you can also make your own NSButton and assigning the NSTrackingArea in it.

Here is a really simple and elegant way to do it, thanks to Joey Zhou : https://github.com/Swift-Kit/JZHoverNSButton

It is written in Swift 2 but XCode will automatically translate it in Swift 3 - 4 without any issue.

Hope it can help someone

娇女薄笑 2024-11-16 17:47:39

这是一个简单的代码,用于跟踪某些控件(图像、标签等)上的鼠标进入鼠标退出事件:

@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 ???")
        }
    }
}

This is a simple code to track mouse enter and mouse exit events on some controls (Images, Label, etc...):

@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 ???")
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文