NSButton:在悬停时显示备用图像

时间:2013-11-08 13:02:57

标签: objective-c nsbutton

我有NSButton同时包含图像备用图像。我想在悬停时显示替代图像。为了解决这个问题,我扩展了 NSButton ,以便在悬停视图时显示备用图像。有更好的解决方案吗?

我的解决方案:

@interface HoverButton()
@property (nonatomic, strong) NSTrackingArea *trackingArea;
@property (nonatomic, strong) NSImage *imageTmp;
@end

@implementation HoverButton

-(void)mouseEntered:(NSEvent *)theEvent {
    [super mouseEntered:theEvent];

    [self updateImages];
    self.image = self.alternateImage;
}

-(void)mouseExited:(NSEvent *)theEvent {
    [super mouseExited:theEvent];

    self.image = self.imageTmp;
}

- (void)updateImages {
    self.imageTmp = self.image;
}

-(void)updateTrackingAreas
{
    if(self.trackingArea != nil) {
        [self removeTrackingArea:self.trackingArea];
    }

    int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);
    self.trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
                                                     options:opts
                                                       owner:self
                                                    userInfo:nil];

    [self addTrackingArea:self.trackingArea];
}


@end

2 个答案:

答案 0 :(得分:0)

我想说这更适合NSButtonCell子类。你可以用一种方法来做它并不适用于所有的NSButton(我怀疑那是你真正想要的)。只需将IB中的按钮单元格类型设置为自定义子类。

这里有一些我刚编写并测试过的代码:

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
    if (_alternateImageOrKeyEquivalentFont && _bcFlags2.mouseInside) {
        // the draw bezel call is optional. maybe you don't want it
        [self drawBezelWithFrame:cellFrame inView:controlView];
        [self drawImage:_alternateImageOrKeyEquivalentFont
              withFrame:cellFrame
                 inView:controlView];
    } else {
        [super drawInteriorWithFrame:cellFrame
                              inView:controlView];
    }
}

您需要在showsBorderOnlyWhileMouseInside方法中将YES设置为init

答案 1 :(得分:0)

CustomButton.h

@interface CustomButton : NSButton
@property (getter=isMouseInside) BOOL mouseInside;
@end

CustomButton.m

@implementation CustomButton

+ (Class)cellClass
{
    return [CustomButtonCell class];
}

- (instancetype)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        [self commonCustomButtonInit];
    }
    return self;
}

- (void)commonCustomButtonInit
{
    NSTrackingArea *trackingArea = nil;
    trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
                                                options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingInVisibleRect
                                                  owner:self
                                               userInfo:nil];

    [self addTrackingArea:trackingArea];
}


- (void)mouseEntered:(NSEvent *)event
{
    self.mouseInside = YES;
    if ([self.cell isKindOfClass:[CustomButtonCell class]])
    {
        CustomButtonCell *cell = self.cell;
        cell.mouseInside = YES;
    }
}

-(void)mouseExited:(NSEvent *)event
{
    self.mouseInside = NO;
    if ([self.cell isKindOfClass:[CustomButtonCell class]])
    {
        CustomButtonCell *cell = self.cell;
        cell.mouseInside = NO;
    }
}

@end

CustomButtonCell.h

@interface CustomButtonCell : NSButtonCell
@property (getter=isMouseInside) BOOL mouseInside;
@end

CustomButtonCell.m

@implementation CustomButtonCell
@end

另见answer