Simple mouseover effect on NSButton

后端 未结 7 689
Happy的楠姐
Happy的楠姐 2021-02-04 01:51

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

相关标签:
7条回答
  • 2021-02-04 02:05

    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");
    
    }
    
    0 讨论(0)
  • 2021-02-04 02:06

    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 ???")
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-04 02:11

    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!")
                }
            }
        }
    
    0 讨论(0)
  • 2021-02-04 02:11

    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

    0 讨论(0)
  • 2021-02-04 02:14

    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]; 
    
    0 讨论(0)
  • 2021-02-04 02:14

    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.

    0 讨论(0)
提交回复
热议问题