В этой части - как сделать резидентное приложение, у которого видна только иконка в статусной панели.
Интерфейс программы
Сначала создадим графический интерфейс программы. Интерфейс программы находится в файле MainMenu.xib. При открытии этого файла запустится "Interface Builder" - встроенный в Xcode графический редактор для создания интерфейса приложения.
Сейчас в редакторе видна только панель меню - вверху, где жирно написано название приложения "Apptest" и прочие стандартные пункты меню. Кроме того, в интефейсе есть основное окно приложения, хоть его в данный момент и не видно. Чтобы его увидеть,нужна щелкнуть на объект "Window" в панели объектов (узкая вертикальная панель слева от сетки редактора).
1. Файл MainMenu.xib открыт в редакторе интерфейса
Ни окно, ни меню нашему резидентному приложению не нужны. Убираем их. Для этого нужно выделить соответствующие объекты в панели объектов и нажать кнопку "Del" на клавиатуре.
Теперь создадим интерфейс нашего резидентного приложения. Это будет простое выпадающее меню.
В правой нижней части Xcode находится библиотека объектов (Object Library). В этой библиотеке нужно найти объект "Меню" (Menu). Для поиска можно воспользоваться строкой поиска в нижней части библиотеки. Найденный объект "Меню" нужно схватить мышкой и перетащить на сетку редактора. На сетке появится выпадающее меню с несколькими пунктами. Обратите внимание - одновременно с этим иконка новго объекта появится и в панели объектов.
Количество пунктов меню можно изменить, просто потянув мышкой за край меню. Сделайте столько пунктов меню, сколько вам нравится:) Затем один из пунктов меню переименуйте в "Quit", этот пункт понадобится нам далее для выхода из программы. Остальные пункты можно оставить как есть - мы их не будем использовать.
2. Интерфейс приложения - выпадающее меню
Реализация выпадающего меню
Теперь напишем код, благодаря которому этот интефейс будет работать.
Сначала откроем файл AppDelegate.h - это заголовочный файл, в нем мы объявим все используемые в приложении переменные. Почему переменные нужно объявлять в заголовочном файле? Зачем вообще нужен заголовочный файл? Загадка.
В файле AppDelegate.h нужно удалить весь имеющийся код и заменить его следующим:
---- код ----
#import
@interface AppDelegate : NSObject {
// Графический интерфейс приложения (меню)
IBOutlet NSMenu *statusMenu;
// Объект статусной панели для размещения иконки приложения
NSStatusItem *statusItem;
// Основная и дополнительная иконки приложения
NSImage *statusImage1;
NSImage *statusImage2;
}
@end---- код ----
Затем откроем файл AppDelegate.m - это файл с исполняемым кодом, в нем мы опишем поведение приложения.
В файле AppDelegate.m нужно удалить весь имеющийся код и заменить его следующим:
---- код ----
#import "AppDelegate.h"
@implementation AppDelegate
// Инициализация приложения
- (void)awakeFromNib {
// Объект статусной панели
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
// Объект для работы с файлами
NSBundle *bundle = [NSBundle mainBundle];
// Загрузка изображений для иконки
statusImage1 = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"icon1" ofType:@"png"]];
statusImage2 = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"icon2" ofType:@"png"]];
// Параметры объекта статусной панели
[statusItem setMenu:statusMenu];
[statusItem setImage:statusImage1];
[statusItem setAlternateImage:statusImage2];
[statusItem setHighlightMode:YES];
[statusItem setToolTip:@"Apptest"];
}
@end
---- код ----
Иконка приложения
Для тестового приложения возьмем вот такую иконку, размером 16x16px:
3. Основное изображение (icon1.png)
4. Дополнительное изображение (icon2.png)
Файлы нужно скопировать в папку Apptest с соответствующими именами (icon1.png и icon2.png). Эти имена указаны в коде, так что назвать файлы нужно именно так.
После добавления файлов в папку нужно добавить их в проект. Для этого нужно в Xcode нажать правой кнопкой на группу Apptest и в контекстном меню выбрать пункт "Add files to Apptest". Далее выбрать ранее скопированные в папку Apptest файлы иконок и добавить их в проект.
Для пущего удобства можно создать в группе Apptest группу Icon (пункт "New Group" в контестном меню группы Apptest) и перенести файлы в эту группу.
5. Файлы иконок добавлены в проект
На этом этапе можно скомпилировать приложение. В статусной панели появится иконка нашего тестового приложения. Ее можно будет нажимать мышкой и она будет правильно подсвечиваться. Интерфейс приложения - меню - пока появляться не будет, для этого еще не все манипуляции сделаны.
6. Иконка запущенного приложения в статусной панели
Связывание иконки и интерфейса приложения
Для того, чтобы щелчок на иконке вызывал появление меню, нужно сделать "связку" иконки и меню. Не знаю, как эта манипуляция правильно называется.
Для этого нужно в Xcode открыть файл интерфейса MainMenu.xib и в панели объектов выбрать объект "App Delegate". Затем в панели утилит (справа) открыть вкладку "Инспектор связей" (Connections inspector).
7. Инспектор связей
В инспекторе связей, в списке "Outlets", есть срока "statusMenu". Это и есть наше выпадающее меню, именно такое название мы дали объекту меню в заголовочном файле.
Для того, чтобы связать объект меню с его графическим интерфейсом, нужно нажать мышкой в кружке справа от объекта и протянуть связь (там потянется такая как бы ниточка) к изображению меню, находящемуся на сетке редактора. Протянув - отпустить мышку. После этого в инспекторе связей будет показана связь объекта "statusMenu" с графическим изображением.
8. Объект меню связан с графическим изображением
На этом этапе можно скомпилировать приложение и посмотреть, как при нажатии иконки появляется меню приложения.
9. Меню приложения
Назначаем функцию пункту меню
Пока что все пункты меню неактивны. Так и должно быть, пока мы не назначим им какую-либо функцию. В данном случае мы назначим функцию выхода из приложения пункту меню "Quit".
Для этого нужно связать пункт "Quit" с назначаемой ему функцией. Функция выхода является стандартной, поэтому нам ничего не нужно будет программировать, все будет сделано одним движением мышки.
В панели объектов нужно выбрать объект "Application". Затем в инспекторе связей, в списке "Received Actions" нужно найти строку "terminate". И, наконец, связать метод "terminate" с пунктом меню "Quit" нашего приложения - просто протянуть мышкой связь от кружочка возле "terminate" до пункта меню "Quit". Созданная связь отобразится в инспекторе связей.
Теперь можно снова скомпилировать приложение. На этот раз пункт "Quit" будет активен и на него можно будет щелкнуть мышкой. Приложение после этого закроется.
Скрытие приложения из Дока и панели меню
Обратите внимание - в Доке показывается иконка нашего приложения. Не та иконка, которую мы используем для статусной панели, а большая иконка для Дока. Поскольку мы не делали такую иконку специально, то используется стандартная.
10. Иконка приложения в Доке
Кроме того, если нажать на эту иконку, то в панели меню появится название приложения Apptest, несмотря на то, что мы удалили панель меню в редакторе интерфейса. Меню удалилось, но вывод названия приложения в панель меню является некой фундаментальной функцией и простым удалением меню от вывода названия не избавиться.
Для того, чтобы убрать иконку из Дока и название из панели меню, нужно сообщить приложению, что оно является резидентной программой.
Щелкните мышкой по заголовку Apptest в проекте. Справа откроются всякие настройки проекта. В списке "TARGETS" выберите Apptest. Далее откройте вкладку "Info".
11. Настройки приложения
В списке "Custom Mac OS X Application Target Properties" нужно навести мышку на любую строку (удобнее на последнюю), появятся две маленькие иконки с изображением плюса и минуса. Нужно нажать на плюс. Это действие добавит в список свойств новою строку и отобразит выпадающий список возможных свойств. Среди этих свойств нужно найти свойство "Application is agent (UIElement)". Затем в правой части строки нужно указать значение этого свойства - "YES".
12. Приложение сделано резидентным
Все, осталось скомпилировать приложение и убедиться, что оно стало настоящим резидентом - видна только иконка в статусной панели.
Репозиторий, бранч
resident.
Часть 1. Создание проекта и настройка репозитория