2009-11-03 11 views
11

Ich möchte die Art, wie ich die Fenstertitelleiste unter OS X zeichne, anpassen. Genauer gesagt möchte ich etwas wie die Twitterrific-App machen, wo es eine benutzerdefinierte Schließen-Schaltfläche, keine Min/Max-Schaltflächen und das Fenster gibt Titeltext ist rechtsbündig. Im Gegensatz zu Twitterrific versuche ich nicht, das gesamte Fenster zu zeichnen (obwohl ich auch nicht komplett dagegen bin).Wie benutzerdefinierte Fenster Titelleiste in Objective-C zeichnen?

Ich habe bereits das RoundWindow-Beispiel auf Cocoa With Love sowie das RoundTransparentWindow-Beispiel von Apple gesehen, aber keines scheint angemessen.

Antwort

6

Wenn Sie keine randlose Fensterklasse verwenden möchten, können Sie einige Dinge tun.

Zuerst können Sie die Close/Min/Max-Tasten kaufen mit -[NSWindow standardWindowButton:] anpassen. Sobald Sie die Schaltfläche erhalten, können Sie sie positionieren/entfernen/etc ...

Sie können den Titel anpassen, indem Sie den Titel auf @"". Dann können Sie eine NSTextField hinzufügen, um Ihren eigenen Titel zu zeichnen, indem Sie die folgenden [[[NSWindow contentView] superview] addSubview:textField] tun.

Dies ist wahrscheinlich der einfachste Weg, Dinge zu tun.

Ein anderer Weg, dies zu tun ist, um die Ansicht zu gestalten, dass all Fenster-Titelleiste zieht, etc ...

die NSWindow Inhalt Ansicht in einer „Thema Ansicht“ ist. Sie können die Themenansicht ableiten und eine eigene Zeichnung erstellen. Das einzige Problem ist, dass die Themenansicht eine private Klasse ist, so dass Sie vorsichtig sein müssen.

+0

Danke, Leibowitzn. Können Sie weitere Einzelheiten zum Einrichten des NSTextFields angeben? Wie stelle ich den Rahmen so ein, dass er richtig im Fenster positioniert ist und wo in meinem Code der beste Platz dafür wäre? – sam

+0

FWIW, ich habe es in der watchFromNib-Methode des App-Controllers getan. Ich positionierte den Rahmen des Textfelds relativ zum Rahmen des Fensters. Dies ist wahrscheinlich nicht der beste Weg, um es zu tun, aber ich habe Benachrichtigungen verwendet, um zu wissen, wann das Fenster zum Hauptfenster wird und/oder damit die Farbe des Textes geändert wird. Nochmals vielen Dank für die Idee. – sam

5

cocoadev bietet einige weitere Informationen darüber, wie Sie am besten Ihre eigene NSWindow Unterklasse implementieren, komplett mit einer Beschreibung der meisten der häufigsten Fallstricke.

Der Kern ist es eine Unterklasse von NSWindow zu erstellen, und legen Sie seine styleMask-NSBorderlessWindowMask in der init-Methode:

- (id) initWithContentRect: (NSRect) contentRect 
       styleMask: (unsigned int) aStyle 
        backing: (NSBackingStoreType) bufferingType 
        defer: (BOOL) flag 
{ 
    if ((self = [super initWithContentRect: contentRect 
           styleMask: NSBorderlessWindowMask 
            backing: bufferingType 
            defer: flag]) == nil) { return nil; } 

    [super setMovableByWindowBackground:YES]; 
    [super setLevel:NSNormalWindowLevel]; 
    [super setHasShadow:YES]; 
    // etc. 

    return self; 
} 

Beachten Sie, dass Sie wahrscheinlich JA für canbecomeKeyWindow, um zurückkehren sollte Ihr Fenster verhalten zu machen wie ein normales Fenster.

- (BOOL) canBecomeKeyWindow 
{ 
    return YES; 
} 

Anschließend können Sie eine benutzerdefinierte NSView Unterklasse erstellen, das gesamte Fenster mit einer Instanz der Klasse füllen, und dann alle entsprechenden Fenster aus dieser benutzerdefinierten Ansicht Zeichnung auszuführen.

Die ganze Sache kann ein bisschen schmerzhaft werden. Sie müssen die meisten normalen Fensterverhalten wie die Größenänderung durch Ziehen der unteren rechten Ecke neu implementieren.

+0

Danke, eJames. Du hast Recht, dass dieser Ansatz (den ich vorher begonnen habe) schmerzhaft werden kann. Ich hatte gehofft, es zu vermeiden, da ich nicht nach einer vollständigen Anpassung suche, und ich möchte nicht die gesamte Standardfunktionalität des Fensters implementieren. Dieser Ansatz ist im Grunde das, was in den Beispielen verwendet wird, auf die ich in meiner Frage verwiesen habe. Ein merkwürdiger Aspekt dieses Ansatzes ist, dass der Schatten des Fensters nicht korrekt zu funktionieren scheint. Es ist nicht so dunkel wie der Schatten in einem Standardfenster und ändert sich nicht, wenn sich der Fokus ändert. Ich denke, das könnte ein Fehler mit dem randlosen Fensterstil sein. – sam

+0

Das Schattenproblem ist bizarr. Es hört sich so an, als ob Leibowitzns Antwort der richtige Weg für dich wäre. Viel Glück damit! –

+0

Das Schattenproblem ist ein langjähriges Problem. Für randlose Fenster mit Tastaturfokus zeichnet Apple keinen dunkleren Schatten. Sehen Sie sich zum Beispiel Stickies an. Laut einem Apple ist der empfohlene Weg, um dies zu umgehen, einen normalen Fenstertyp zu verwenden und dann alle eigenen Zeichnungen zu erstellen. – Leibowitzn

2

Es gibt ein Beispiel für eine benutzerdefinierte Fensterimplementierung im Beispielprojekt CoreData Stickies.

Verwandte Themen