Edytuj : Od kiedy to napisałem, INAppStore zaimplementował całkiem niezły sposób na zrobienie tego z INWindowButton
. Jeśli szukasz rozwiązania typu "przeciągnij i upuść", sprawdź poniższy kod, ale nadal pomoże Ci wdrożyć własne.
Więc nie mogłem znaleźć sposobu na zmianę standardWindowButton
s. Oto opis tworzenia własnych przycisków.
Uwaga: Dostępne są 4 stany przyciski mogą być w
- okna nieaktywnego
- Okno aktywne - normalna
- Okno aktywne - unoszą
- aktywne okno - naciśnij
W przewodniku!
Krok 1: ukryć istniejące wcześniej przyciski
NSButton *windowButton = [self standardWindowButton:NSWindowCloseButton];
[windowButton setHidden:YES];
windowButton = [self standardWindowButton:NSWindowMiniaturizeButton];
[windowButton setHidden:YES];
windowButton = [self standardWindowButton:NSWindowZoomButton];
[windowButton setHidden:YES];
Krok 2: Konfiguracja widoku w konstruktorze Interface
Zauważysz na najechaniu przyciski wszystkie zmiany ich aktywowaniu stan, więc potrzebujemy widoku kontenera, aby podnieść wskaźnik.
- Utwórz widok kontenera o szerokości 54 pikseli i wysokości 16 pikseli.
- Utwórz 3 kwadratowe style
NSButton
s, każdy o rozmiarze 14 pikseli x 16 pikseli w widoku kontenera.
- Przestań przyciskami, aby uzyskać 6px odstępów między nimi.
konfiguracja przycisków
- W Inspektorze atrybutów, należy ustawić właściwość dla każdego przycisku
Image
do okna czynne normalnego obrazu.
- Ustawia właściwość obrazu
Alternate
na obraz aktywowany przez okno.
- Wyłączenie
Bordered
.
- Ustaw
Type
na Momentary Change
.
- Dla każdego przycisku ustawić identyfikator do
close
, minimize
lub zoom
(poniżej zobaczysz, jak można to wykorzystać, aby podklasa NSButton prostsze)
Krok 3: podklasa widok kontenera & przycisków
opakowaniu:
Utwórz nowy plik, podklasy NSView. Tutaj zamierzamy użyć Centrum powiadomień, aby poinformować przyciski, kiedy powinny przejść do swojego stanu zawisu.
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];
}
Przyciski:
Utwórz nowy plik, tym razem podklasę NSButton. Ten jest nieco więcej do wyjaśnienia, więc po prostu opublikuję cały kod.
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
W IB ustawić niestandardową klasę widoku kontenera i wszystkie 3 przyciski do swoich klasach że właśnie utworzone.
Krok 4: Ustaw działania przycisków
Metody te, zwane od kontrolera widok, są takie same jak standardWindowButton
s'. Połącz je z przyciskami w 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];
}
Krok 5: Dodawanie widoku do okna
mam oddzielną konfigurację xib i widok kontrolera specjalnie dla kontroli okiennych. Kontroler widoku nazywa 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];
Nadzieja to pomaga. To dość długa wiadomość, jeśli uważasz, że popełniłem błąd lub coś zostawiłem, daj mi znać.
To nie jest długa wiadomość, to ** świetna ** odpowiedź. Dodane do zakładek do wykorzystania w przyszłości. – sosborn
@sosborn dzięki, doceń informację zwrotną :) –
Ten post nie traktuje problemów, takich jak dostępność i zachowanie na pierwszym myszy. Są trudne do uzyskania ... najlepiej jest użyć przycisków systemu! (Zauważ, że od Yosemite paski narzędzi i paski tytułu okna mogą być łączone, a przyciski okna będą wyśrodkowane w pionie.) – jtbandes