編輯:由於我寫了這個,INAppStore已經實現了一個很好的方式來與INWindowButton
做到這一點。如果您正在尋找拖放解決方案檢查,但下面的代碼仍然可以幫助您實現自己的解決方案。
所以我找不到方法來改變standardWindowButton
s。以下是我如何創建自己的按鈕的演練。
注:有4種狀態的按鈕可以是
- 窗口INACTIVE
- 窗口活性 - 正常
- 窗口活性 - 懸停
- 窗口活性 - 按
在演練!
第1步:隱藏的預先存在的按鈕
NSButton *windowButton = [self standardWindowButton:NSWindowCloseButton];
[windowButton setHidden:YES];
windowButton = [self standardWindowButton:NSWindowMiniaturizeButton];
[windowButton setHidden:YES];
windowButton = [self standardWindowButton:NSWindowZoomButton];
[windowButton setHidden:YES];
第2步:設置在界面生成器視圖
你會發現懸停的按鈕都在改變自己的懸停狀態,所以我們需要一個容器視圖來拾取懸停。
- 創建容器視圖爲54px寬×16px高。
- 創建3個方形樣式
NSButton
s,每個14px寬×16px高的容器視圖內。
- 將按鈕分隔開來,所以它們之間有6px的空白。
設置的按鈕
- 在屬性檢查員,所述
Image
屬性爲每個按鈕設定爲窗口活性正常圖像。
- 將
Alternate
圖像屬性設置爲窗口活動按下圖像。
- 轉過
Bordered
關閉。
- 將
Type
設置爲Momentary Change
。
- 對於每個按鈕設置標識符
close
,minimize
或zoom
(下面你會看到你如何使用這個方法,使NSButton子類簡單)
第3步:子類的容器視圖&按鈕
集裝箱:
創建一個新的文件,子類的NSView。在這裏,我們將使用通知中心告訴按鈕何時切換到懸停狀態。
HMTrafficLightButtonsContainer.m
// Tells the view to pick up the hover event
- (void)viewDidMoveToWindow {
[self addTrackingRect:[self bounds]
owner:self
userData:nil
assumeInside:NO];
}
// When the mouse enters/exits we send out these notifications
- (void)mouseEntered:(NSEvent *)theEvent {
[[NSNotificationCenter defaultCenter] postNotificationName:@"HMTrafficButtonMouseEnter" object:self];
}
- (void)mouseExited:(NSEvent *)theEvent {
[[NSNotificationCenter defaultCenter] postNotificationName:@"HMTrafficButtonMouseExit" object:self];
}
按鈕:
創建一個新的文件,這個時候子類NSButton。這一個更多的解釋,所以我只是發佈所有的代碼。
HMTrafficLightButton.m
@implementation HMTrafficLightButton {
NSImage *inactive;
NSImage *active;
NSImage *hover;
NSImage *press;
BOOL activeState;
BOOL hoverState;
BOOL pressedState;
}
-(id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self setup];
}
return self;
}
- (id)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
if (self) {
[self setup];
}
return self;
}
- (void)setup {
// Setup images, we use the identifier to chose which image to load
active = [NSImage imageNamed:[NSString stringWithFormat:@"window-button-%@-active",self.identifier]];
hover = [NSImage imageNamed:[NSString stringWithFormat:@"window-button-%@-hover",self.identifier]];
press = [NSImage imageNamed:[NSString stringWithFormat:@"window-button-%@-press",self.identifier]];
inactive = [NSImage imageNamed:@"window-button-all-inactive"];
// Checks to see if window is active or inactive when the `init` is called
if ([self.window isMainWindow] && [[NSApplication sharedApplication] isActive]) {
[self setActiveState];
} else {
[self setInactiveState];
}
// Watch for hover notifications from the container view
// Also watches for notifications for when the window
// becomes/resigns main
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(setActiveState)
name:NSWindowDidBecomeMainNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(setInactiveState)
name:NSWindowDidResignMainNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(hoverIn)
name:@"HMTrafficButtonMouseEnter"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(hoverOut)
name:@"HMTrafficButtonMouseExit"
object:nil];
}
- (void)mouseDown:(NSEvent *)theEvent {
pressedState = YES;
hoverState = NO;
[super mouseDown:theEvent];
}
- (void)mouseUp:(NSEvent *)theEvent {
pressedState = NO;
hoverState = YES;
[super mouseUp:theEvent];
}
- (void)setActiveState {
activeState = YES;
if (hoverState) {
[self setImage:hover];
} else {
[self setImage:active];
}
}
- (void)setInactiveState {
activeState = NO;
[self setImage:inactive];
}
- (void)hoverIn {
hoverState = YES;
[self setImage:hover];
}
- (void)hoverOut {
hoverState = NO;
if (activeState) {
[self setImage:active];
} else {
[self setImage:inactive];
}
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end
在IB設置的容器視圖的自定義類,所有3個按鈕各自的類,我們剛剛創建。
步驟4:設定按鈕動作
這些方法中,從視圖控制器調用,是一樣的standardWindowButton
S'。將它們鏈接到IB中的按鈕。
- (IBAction)clickCloseButton:(id)sender {
[self.view.window close];
}
- (IBAction)clickMinimizeButton:(id)sender {
[self.view.window miniaturize:sender];
}
- (IBAction)clickZoomButton:(id)sender {
[self.view.window zoom:sender];
}
5步:添加視圖到窗口
我對窗口控件單獨XIB和視圖控制器設置具體。視圖控制器被稱爲HMWindowControlsController
(HMWindowControlsController*) windowControlsController = [[HMWindowControlsController alloc] initWithNibName:@"WindowControls" bundle:nil];
NSView *windowControlsView = windowControlsController.view;
// Set the position of the window controls, the x is 7 px, the y will
// depend on your titlebar height.
windowControlsView.frame = NSMakeRect(7.0, 10.0, 54.0, 16.0);
// Add to target view
[targetView addSubview:windowControlsView];
希望這有助於。這是一篇相當冗長的文章,如果您認爲我犯了一個錯誤或者遺漏了某些內容,請告訴我。
這不是一個冗長的帖子,它是一個**很棒的**答案。爲未來參考收藏。 – sosborn
@sosborn謝謝,欣賞反饋:) –
本文不處理可訪問性和第一鼠標行爲等問題。這些都很難得到正確的...最好的事情就是使用系統的按鈕! (請注意,截至優勝美地,工具欄和窗口標題欄可以組合,窗口按鈕將垂直居中。) – jtbandes