Как настроить строку заголовка окна рисования в Objective-C?

Я хотел бы настроить способ рисования строки заголовка окна в OS X. В частности, я хотел бы сделать что-то вроде приложения Twitterrific, где есть пользовательская кнопка закрытия, кнопки min/max и текст заголовка окна имеет правомерное значение. В отличие от Twitterrific, я не собираюсь настраивать все окно (хотя я тоже не против этого).

Я уже видел образец RoundWindow на Cocoa с любовью, а также пример RoundTransparentWindow, который Apple предоставляет, но не кажется подходящим.

Ответ 1

Если вы не хотите использовать класс окон без полей, вы можете сделать пару вещей.

Сначала вы можете настроить кнопки close/min/max с помощью -[NSWindow standardWindowButton:]. Как только вы получите кнопку, вы можете поместить ее/удалить/etc...

Вы можете настроить заголовок, установив заголовок на @"". Затем вы можете добавить NSTextField, чтобы нарисовать свой собственный заголовок, выполнив следующие [[[NSWindow contentView] superview] addSubview:textField].

Это, наверное, самый простой способ сделать что-то.

Другой способ сделать это - настроить представление, которое рисует всю строку заголовка окна и т.д.

Просмотр содержимого NSWindow находится в "представлении темы". Вы можете подклассифицировать тему и сделать свой собственный чертеж. Единственная проблема заключается в том, что тематическое представление представляет собой частный класс, поэтому вам нужно быть осторожным.

Ответ 2

cocoadev содержит более подробную информацию о том, как наилучшим образом реализовать свой собственный подкласс NSWindow, в комплекте с описанием большей части общие подводные камни.

Суть его в том, чтобы создать подкласс NSWindow и установить его styleMask в NSBorderlessWindowMask в методе init:

- (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;
}

Обратите внимание, что вы должны, вероятно, вернуть YES для canbecomeKeyWindow, чтобы ваше окно выглядело как обычное окно.

- (BOOL) canBecomeKeyWindow
{
    return YES;
}

Затем вы можете создать пользовательский подкласс NSView, заполнить все окно экземпляром указанного класса и затем выполнить весь соответствующий чертеж окна из этого пользовательского представления.

Все это может стать немного болезненным. Вам нужно будет повторно выполнить большинство обычных действий окна, таких как изменение размера, перетащив нижний правый угол.

Ответ 3

Вот пример реализации пользовательского окна в примере проекта CoreData Stickies.