Pull to refresh

Comments 22

В App Store, интересно, пропустят, если использовать приватные API? Что-то мне подсказывает, что нет
В AppStore достаточно много программ, использующих нестандартные заголовки. Не могу судить, пользовались ли они такими методами, но не исключаю такой возможности.
А вы не пробовали смотреть реализацию такого, скажем, в Google Chrome? Может, есть какой-то более-менее «прямой» способ без реверс-инженеринга внутренних классов? Ибо в Apple оооочень просят не юзать недокументированные API, потому что их приложение может легко сломаться в следующих версиях ОС (это касается больше iOS, но для Mac OS X тоже справедливо, в общем-то)
> это касается больше iOS
Они не просят, они просто отклоняют такие приложения
Ну вот здесь автор, вроде как, не использует недокументированные API напрямую, а просто берет superView от самого верхнего view, доступного «просто так» — такое, ИМХО, непросто отловить при автоматическом анализе приложения. Ну а на использование method_exchangeImplementations, насколько я помню, не было ограничений вплоть до iOS 5, в котором, вроде как, исходя из комментариев к этому топику, его больше не рекомендуют использовать.
Я не это имел ввиду, такие фокусы я с UIWebView делал, не реджектили.

А тут автор использует

class_addMethod
method_exchangeImplementations

За которые в аппсор не ускают.
1. Приватные API в этом примере никто не использует. Имеет место быть рантайм подстановка стандартного метода drawRect: родительского объекта. _drawTitleStringIn — приватный метод, его подстановка — не очень красивое решение, без него, кстати, можно легко обойтись тем же drawRect:

2. Пропустят. Моё приложение в AppStore использует этот принцип для кастомизации окна. BookReader, если что.
Было бы интересно почитать про хитрости взаимодействия Qt с Cocoa
А в чём сложность это сделать «легально», просто используя несложный подкласс NSWindow? Примеров масса. В Адресная книга и iCal, я думаю, так и реализовано.

Т.е. смысл использования недокументированного API в данном случае сомнителен (по крайней мере для меня).

Возможно, дело именно в том, что автор юзает не просто Cocoa, а Qt+Cocoa и у него какие-то сложности с тем, чтобы задавать другой класс вместо NSWindow..?
Тут вопрос в простоте. Реализовывать свой сабкласс от NSWindow было быдостаточно дорогим удовольствием, кроме того, для внедрения его в уже готовый проект потребовалось бы много времени.

И да, как заметили ниже, я исходил из ограничений Qt, и очень не хотелось модифицировать пересобирать весь фреймворк ради изменения цвета заголовка окна.
Сложность вот в чем: если вы используете borderless window, окно перестаёт быть resizable. Для MacOS X 10.4-10.6 это не было проблемой, так как ресайзер находился в нижнем правом углу и было раз плюнуть прилепить свой обработчик ресайза. В MacOS X 10.7 Lion ресайз окна происходит со всех сторон, при этом при наведении мыши на край окна нужно менять курсор на стрелочки. Я не хочу сказать, что это невозможно, это возможно, но геморройно. Легче подменить райнтайм метод и сделать все что нужно, даже убрать titlebar.
Я детально не изучал этот вопрос. Но гугл в первых же ссылках приводит пример — github.com/indragiek/INAppStoreWindow.

Небольшой подкласс NSWindow со всеми вытекающими. Пример программы оттуда же работает без каких-либо проблем.
Сорри, но вы не в теме. Я не знаю какой вам кайф писать о том, в чем не разбираетесь, но хоть бы удосужились посмотреть что делает пример по вашей ссылке.
А делает он в основном следующее:

NSView *themeFrame = [contentView superview]; // берем NSThemeFrame
NSView *firstSubview = [[themeFrame subviews] objectAtIndex:0]; // берем первую дочернюю NSView
[_titleBarView setAutoresizingMask:(NSViewMinYMargin | NSViewWidthSizable)];
[self _recalculateFrameForTitleBarView];
[themeFrame addSubview:_titleBarView positioned:NSWindowBelow relativeTo:firstSubview]; // добавляем самодельный тайтлбар к NSThemeFrame под первой дочерней NSView

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

Ух, как Вы грозно. Я не понимаю, зачем быть в какой-то «теме», чтобы увидеть, что первый же приведённый пример по ссылке — это NSWindow с полностью кастомным «легальным» заголовком, и он ровно опровергает Ваши доводы про «ресайз» в 10.7.

Не кипятитесь, я нисколько не сомневаюсь в Вашей компетенции, уступлю (если это так важно) — я не гордый.
lymes просто показал, что приведённый Вами способ использует всё тот же NSThemeFrame, но при этом не делается никаких проверок. Тут тоже, можно сказать, используются недокументированные возможности — как минимум, некоторые факты из жизни NSThemeFrame. Хоть и неявно.
Неа, не опровергает. Объясню почему: в приведенном вами примере не используется borderless window, а используется некий костыль, прилепленный к тому же приватному NSThemeFrame.
Этот костыль (кастомнй тайтлбар на основе NSView),
— добавляет оверхед в интерфейс,
— точно так же затрагивает приватную часть окна (NSThemeFrame)

Чистое же решение, классический пример кастомизации NSWindow — это объект с флагом NSBorderlessWindowMask в маске стилей. И в этом случае код имплементации окна для Лайон действительно займёт намного больше.

И да, чуть не забыл, в Лайон borderless окна не могут быть full-screen. Из-за этого приведенный автором статьи пример кастомизации окна остаётся чуть ли не единственно приемлемым.
Очень интересно про Qt. У меня здоровенная софтина на Qt и хочется ей кастомизировать заголовок.

А пока, увы, даже иконку сделать не получается =((
Иконка делается элементарно.

Если это иконка самого приложения (которая будет отображаться в Finder'е), то в .pro файле надо написать что-то типа того:

macx: ICON = myicon.icns

Сам файл .icns можно сделать в любом редакторе, его поддерживающем, так же существуют онлайн-конвертеры, которым можно скормить несколько png файлов разного размера и получить на выходе .icns для программы.

Если же нужно установить иконку для конкретного окна, то всё ещё проще — QWidget::setWindowIcon() или QApplication::setWindowIcon().

А вообще, это очень хорошо описано в документации.
Яхууу! Спасибо, не буду париться написанием своего солюшена :)
UFO just landed and posted this here
Sign up to leave a comment.

Articles