2011-10-03 67 views
11

加在我的應用我改變standardWindowButtons的位置接近/ miniturize /擴大,像這樣:可可/ OSX - NSWindow standardWindowButton的行爲出現異常複製一次又一次

//Create the buttons 
    NSButton *minitButton = [NSWindow standardWindowButton:NSWindowMiniaturizeButton forStyleMask:window.styleMask]; 
NSButton *closeButton = [NSWindow standardWindowButton:NSWindowCloseButton forStyleMask:window.styleMask]; 
NSButton *fullScreenButton = [NSWindow standardWindowButton:NSWindowZoomButton forStyleMask:window.styleMask]; 


//set their location 
[closeButton setFrame:CGRectMake(7+70, window.frame.size.height - 22 - 52, closeButton.frame.size.width, closeButton.frame.size.height)]; 
[fullScreenButton setFrame:CGRectMake(47+70, window.frame.size.height - 22 -52, fullScreenButton.frame.size.width, fullScreenButton.frame.size.height)]; 
[minitButton setFrame:CGRectMake(27+70, window.frame.size.height - 22 - 52, minitButton.frame.size.width, minitButton.frame.size.height)]; 

//add them to the window 
[window.contentView addSubview:closeButton]; 
[window.contentView addSubview:fullScreenButton]; 
[window.contentView addSubview:minitButton]; 

現在,當使用按鈕有出現的窗口是兩個問題: 1.他們是灰色的,而不是他們的正確顏色 2.當鼠標在他們身上時,他們不顯示+或x標誌

任何人都可以告訴我我做錯了什麼。謝謝。

回答

-1

呼叫[button highlight:yes]每個按鈕。

+7

可悲的是'[按鈕高亮:YES]。'只有繪製窗口按鈕的「按下」狀態([參考](http://www.cocoabuilder.com /archive/cocoa/76398-standardwindowbuttons.html))。我還不知道尚未繪製「懸停」狀態的方法。 – rentzsch

0

你不會再添加。你將它們移動到contentView。這些按鈕最初在window.contentView.superview中。

[window.contentView.superview addSubview:closeButton]; 
[window.contentView.superview addSubview:fullScreenButton]; 
[window.contentView.superview addSubview:minitButton]; 

應該讓你正確的行爲,而不需要trackingArea。

10

下面是這個懸停神奇的機制:繪製本身標準圓圈按鈕之前(如NSWindowMiniaturizeButton)調用其superview無證方法_mouseInGroup:。如果此方法返回YES帶圓圈的按鈕在內部繪製圖標。就這樣。

如果你把你自己的視圖中這些按鈕,你可以簡單地實現這個方法,當你想控制這個鼠標懸停外觀。如果你只是移動或重新佈局這些按鈕,他們仍然是subview S的NSThemeFrame(或類似的東西),你必須調酒方法_mouseInGroup:這個類的,大概是因爲我們有非常簡單的以前的方法確實不值得。

在我來說,我有自定義NSView包含我的標準按鈕作爲subview S和這個代碼使上述所有魔法描述:

- (void)updateTrackingAreas 
{ 
    NSTrackingArea *const trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingInVisibleRect) owner:self userInfo:nil]; 
    [self addTrackingArea:trackingArea]; 
} 

- (void)mouseEntered:(NSEvent *)event 
{ 
    [super mouseEntered:event]; 
    self.mouseInside = YES; 
    [self setNeedsDisplayForStandardWindowButtons]; 
} 

- (void)mouseExited:(NSEvent *)event 
{ 
    [super mouseExited:event]; 
    self.mouseInside = NO; 
    [self setNeedsDisplayForStandardWindowButtons]; 
} 

- (BOOL)_mouseInGroup:(NSButton *)button 
{ 
    return self.mouseInside; 
} 

- (void)setNeedsDisplayForStandardWindowButtons 
{ 
    [self.closeButtonView setNeedsDisplay]; 
    [self.miniaturizeButtonView setNeedsDisplay]; 
    [self.zoomButtonView setNeedsDisplay]; 
} 
1

我充分認識到這個問題Valentin Shergin's answer正確。它可以防止利用任何私人API,不像Google did in Chrome。只是想分享那些不喜歡子NSView誰只是把這些按鈕在一個已經存在的視圖(如self.window.contentView)的方法。

正如我只是想通過setFrame:重新定位NSWindowButton S,我發現,一旦窗戶調整,跟蹤區域似乎「修復」自己自動的沒有任何私有API的使用 (至少在10.11)。

因此,你可以不喜歡的東西下面的申請「假調整」給你重新定位你的按鈕窗口:

NSRect frame = [self.window frame]; 
frame.size = NSMakeSize(frame.size.width, frame.size.height+1.f); 
[self.window setFrame:frame display:NO animate:NO]; 
frame.size = NSMakeSize(frame.size.width, frame.size.height-1.f); 
[self.window setFrame:frame display:NO animate:YES]; 

(我做了它在我的主窗口的NSWindowDelegatewindowDidBecomeMain:。只要加載窗口應該工作和可見