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 ответа
Я бы сказал, что это лучше подходит для 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
метод для клетки.
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
Также смотрите этот ответ.