我正在为自定义渲染创建一个自定义NSButtonCell
。
现在,我想有不同的方面,取决于鼠标是否在按钮上。我怎样才能得到这些信息?
感谢和问候,
这是我完美地为自己创造和工作的。。。
步骤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");
}
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"]
然后,您可以在mouseEntered和mouseExited函数中编写开关用例或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!")
}
}
}
您需要对NSButton类(或者更好的是NSButtonCell类)进行子类划分。正如Justin所说,如果你把两种方法
- (void)mouseEntered:(NSEvent *)theEvent;
- (void)mouseExited:(NSEvent *)theEvent;
当鼠标进入和退出该区域时,应该调用它们。您可能还需要重新创建跟踪区域,请查看此处:
- (void)updateTrackingAreas
对于淡入淡出效果,我与动画师和alpha值一起玩,例如:
[self animator]setAlphaValue:0.5];
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
}
一个良好的起点,在NSResponder:中声明
- (void)mouseEntered:(NSEvent *)theEvent;
- (void)mouseExited:(NSEvent *)theEvent;
具体来说,按钮单元格的容器(而不是单元格本身)是NSResponder。
对于那些喜欢子类化的人,您也可以制作自己的NSButton
并在其中分配NSTrackingArea
。
这是一个非常简单优雅的方法,感谢周:https://github.com/Swift-Kit/JZHoverNSButton
它是用Swift 2编写的,但XCode将自动在Swift 3-4中进行翻译,不会出现任何问题。
希望它能帮助
这是一个简单的代码,用于跟踪某些控件(图像、标签等)上的mouse enter
和mouse 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 ???")
}
}
}