Windows

Для каждого приложения для iOS нужно по крайней мере одно окно — экземпляр UIWindow класс — и некоторые могут включать больше чем одно окно. Объект окна имеет несколько ответственности:

В iOS окна не имеют строк заголовка, рамок для закрытия или любых других визуальных украшений. Окно является всегда просто пустым контейнером для одного или более представлений. Кроме того, приложения не изменяют свое содержание путем показа новых окон. Когда Вы хотите изменить выведенное на экран содержание, Вы изменяете frontmost представления своего окна вместо этого.

Большинство приложений для iOS создает и использует только одно окно во время своего времени жизни. Это окно охватывает весь основной экран устройства и загружается из основного файла пера приложения (или создается программно), рано в сроке действия приложения. Однако, если поддержка приложений использование внешнего дисплея для видео, это может создать дополнительное окно для отображения содержания на том внешнем дисплее. Все другие окна обычно создаются системой и обычно создаются в ответ на определенные события, такие как входящий телефонный вызов.

Задачи, включающие Windows

Для многих приложений единственное время, приложение взаимодействует со своим окном, - когда это создает окно при запуске. Однако можно использовать объект окна приложения для выполнения нескольких связанных с приложением задач:

Создание и конфигурирование окна

Можно создать и сконфигурировать главное окно приложения программно или использующий Интерфейсного Разработчика. В любом случае Вы создаете окно во время запуска и должны сохранить его и сохранить ссылку на него в Вашем делегате приложения объект. Если Ваше приложение создает дополнительные окна, имейте приложение, создают их лениво, когда они необходимы. Например, если Ваша поддержка приложений, выводящая на экран содержание на внешнем дисплее, это должно ожидать, пока дисплей не подключается прежде, чем создать соответствующее окно.

Необходимо всегда создавать главное окно приложения во время запуска независимо от того, запускается ли приложение в передний план или фон. Создание и конфигурирование окна не являются дорогой работой отдельно. Однако, если Ваше приложение запускается прямо в фон, необходимо избежать делать окно видимым, пока приложение не вводит передний план.

Создание Windows в интерфейсном разработчике

Создание Разработчика Интерфейса использования главного окна Вашего приложения просто, потому что шаблоны проекта XCode делают это для Вас. Каждый новый проект приложения XCode включает основной файл пера (обычно с именем MainWindow.xib или некоторый вариант этого), который включает главное окно приложения. Кроме того, эти шаблоны также определяют выход для того окна в делегате приложения объект. Вы используете этот выход для доступа к объекту окна в коде.

При переоснащении проекта использовать Интерфейсного Разработчика создавание Разработчика Интерфейса использования окна является простым вопросом перетаскивания объекта окна к файлу пера. Конечно, необходимо также сделать следующее:

  • Для доступа к окну во время выполнения необходимо подключить окно к выходу, обычно один определенный в делегате приложения или Владельце Файла файла пера.

  • Если Ваши планы переоснащения включают то, чтобы заставлять Ваше новое перо зарегистрировать основной файл пера Вашего приложения, необходимо также установить NSMainNibFile введите свое приложение Info.plist файл к имени Вашего файла пера. Изменение значения этого ключа гарантирует, что файл пера загружается и доступен для использования к этому времени application:didFinishLaunchingWithOptions: метод Вашего делегата приложения вызывают.

Для получения дополнительной информации о создании и конфигурировании файлов пера, см. Интерфейсное Руководство пользователя Разработчика. Для получения информации о том, как загрузить файлы пера в Ваше приложение во время выполнения, посмотрите Файлы Пера в Руководстве по программированию Ресурса.

Создание окна программно

Если Вы предпочитаете создавать главное окно своего приложения программно, необходимо включать код, подобный следующему в application:didFinishLaunchingWithOptions: метод Вашего делегата приложения:

self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

В предыдущем примере, self.window как предполагается, заявленное свойство Вашего делегата приложения, сконфигурированного для сохранения объекта окна. При создании окна для внешнего дисплея вместо этого, Вы присвоили бы его различной переменной, и необходимо было бы указать границы не основного UIScreen объект, представляющий тот дисплей.

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

Добавление содержания к окну

Каждое окно обычно имеет единственный корневой объект представления (управляемый соответствующим контроллером представления), который содержит все другие представления, представляющие Ваше содержание. Используя единственное корневое представление упрощает процесс изменения Вашего интерфейса; для отображения нового содержания все, что необходимо сделать, заменить корневое представление. Для установки представления в окне используйте addSubview: метод. Например, для установки представления, которым управляет контроллер представления Вы использовали бы код, подобный следующему:

[window addSubview:viewController.view];

Вместо предыдущего кода, можно альтернативно сконфигурировать rootViewController свойство окна в Вашем файле пера. Это свойство предлагает удобный способ сконфигурировать корневое представление окна с помощью файла пера вместо программно. Если это свойство установлено, когда окно загружается из его файла пера, UIKit автоматически устанавливает представление от связанного контроллера представления как корневое представление окна. Это свойство используется только для установки корневого представления и не используется окном для передачи с контроллером представления.

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

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

Изменение уровня окна

Каждый UIWindow объект имеет конфигурируемое windowLevel свойство, определяющее, как то окно расположено относительно других окон. По большей части Вы не должны должны быть изменять уровень окон своего приложения. Новые окна автоматически присваиваются нормальному уровню окна во время создания. Нормальный уровень окна указывает, что окно представляет связанное с приложением содержание. Более высокие уровни окна резервируются для получения информации, которая должна плавать выше содержимого приложения, такого как панель состояния системы или предупредительные сообщения. И несмотря на то, что можно присвоить окна этим уровням сами, система обычно делает это для Вас при использовании определенных интерфейсов. Например, когда Вы показываете или скрываете строку состояния или выводите на экран предупредительное представление, система автоматически создает необходимые окна для отображения тех элементов.

Наблюдение изменений окна

Если Вы хотите отследить появление или исчезновение окон в Вашем приложении, можно сделать настолько использующий эти связанные с окном уведомления:

Эти уведомления поставлены в ответ на программируемые изменения в окнах Вашего приложения. Таким образом, когда Ваше приложение показывает или скрывает окно, UIWindowDidBecomeVisibleNotification и UIWindowDidBecomeHiddenNotification уведомления поставлены соответственно. Когда Ваше приложение перемещается в фоновый режим выполнения, эти уведомления не поставлены. Даже при том, что Ваше окно не выведено на экран на экране, в то время как Ваше приложение в фоновом режиме, это все еще считают видимым в контексте Вашего приложения.

UIWindowDidBecomeKeyNotification и UIWindowDidResignKeyNotification уведомления помогают Вашему приложению отслеживать, которых окно является ключевым окном — т.е. какое окно в настоящее время получает события клавиатуры и другой не связанные с касанием события. Принимая во внимание, что сенсорные события поставлены окну, в котором произошло касание, события, не имеющие связанного координатного значения, поставлены ключевому окну Вашего приложения. Только одно окно за один раз может быть ключевым.

Отображение содержания на внешнем дисплее

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

UIScreen класс ведет список объектов на экране, представляющих доступные аппаратные дисплеи. Обычно, существует только один объект на экране, представляющий основной дисплей для любого основанного на iOS устройства, но устройства, поддерживающие соединение с внешним дисплеем, могут иметь дополнительный объект на экране в наличии. Устройства, поддерживающие внешний дисплей, включают iPhone и устройства iPod touch, имеющие дисплеи Сетчатки и iPad. Более старые устройства, такие как iPhone 3GS, не поддерживают внешние дисплеи.

Процесс для отображения содержания на внешнем дисплее описан в следующих разделах. Однако следующие шаги суммируют базовый процесс:

  1. При запуске приложения зарегистрируйтесь для экранного соединения и уведомлений разъединения.

  2. Когда пора вывести на экран содержание на внешнем дисплее, создать и сконфигурировать окно.

    • Используйте screens свойство UIScreen получить объект на экране для внешнего дисплея.

    • Создайте a UIWindow объект и размер это соответственно для экрана (или для Вашего содержания).

    • Присвойтесь UIScreen объект для внешнего дисплея к screen свойство окна.

    • Скорректируйте разрешение объекта на экране по мере необходимости для поддержки содержания.

    • Добавьте любые надлежащие представления к окну.

  3. Покажите окно и обновляйте его обычно.

Обработка экранных уведомлений соединения и разъединения

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

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

Перечисление 2-1 показывает, что код раньше регистрировался для уведомлений разъединения и соединения. Этот метод вызывает делегат приложения во время инициализации, но Вы могли зарегистрироваться для этих уведомлений от других мест в Вашем приложении, также. Реализация методов обработчиков показана в Перечислении 2-2.

Перечисление 2-1  , Регистрирующееся для экранного подключения и уведомлений разъединения

- (void)setupScreenConnectionNotificationHandlers
{
    NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
 
    [center addObserver:self selector:@selector(handleScreenConnectNotification:)
            name:UIScreenDidConnectNotification object:nil];
    [center addObserver:self selector:@selector(handleScreenDisconnectNotification:)
            name:UIScreenDidDisconnectNotification object:nil];
}
 

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

Перечисление 2-2 показывает, как создать вторичное окно и заполнить его некоторым содержанием. В этом примере приложение создает окно в методах обработчиков, которые это использует для получения экранных уведомлений соединения. (Для получения информации о регистрации для соединения и уведомлений разъединения, см. Перечисление 2-1.) Метод обработчиков для уведомления соединения создает вторичное окно, связывает его с недавно связанным экраном и вызывает метод основного контроллера представления приложения, чтобы добавить некоторое содержание к окну и показать его. Метод обработчиков для уведомления разъединения выпускает окно и уведомляет основной контроллер представления так, чтобы это могло скорректировать свое представление соответственно.

Перечисление 2-2  , Обрабатывающее подключение и уведомления разъединения

- (void)handleScreenConnectNotification:(NSNotification*)aNotification
{
    UIScreen*    newScreen = [aNotification object];
    CGRect        screenBounds = newScreen.bounds;
 
    if (!_secondWindow)
    {
        _secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
        _secondWindow.screen = newScreen;
 
        // Set the initial UI for the window.
        [viewController displaySelectionInSecondaryWindow:_secondWindow];
    }
}
 
- (void)handleScreenDisconnectNotification:(NSNotification*)aNotification
{
    if (_secondWindow)
    {
        // Hide and then delete the window.
        _secondWindow.hidden = YES;
        [_secondWindow release];
        _secondWindow = nil;
 
        // Update the main screen based on what is showing here.
        [viewController displaySelectionOnMainScreen];
    }
 
}

Конфигурирование окна для внешнего дисплея

Для отображения окна на внешнем экране необходимо связать его с корректным объектом на экране. Этот процесс включает определение местоположения надлежащего UIScreen объект и присвоение его к окну screen свойство. Можно получить список объектов на экране от screens метод класса UIScreen. Массив, возвращенный этим методом всегда, содержит по крайней мере один объект, представляющий основной экран. Если второй объект присутствует, тот объект представляет связанный внешний дисплей.

Перечисление 2-3 показывает метод, который вызывают при запуске приложения, чтобы видеть, присоединяется ли уже внешний дисплей. Если это, метод создает окно, связывает его с внешним дисплеем и добавляет некоторое содержание заполнителя прежде, чем показать окно. В этом случае содержание заполнителя является белым фоном и меткой, указывающей, что нет никакого содержания для отображения. Для показа окна этот метод изменяет значение hidden свойство вместо вызова makeKeyAndVisible. Это делает это, потому что окно содержит только статическое содержание и не используется для обработки событий.

Перечисление 2-3  , Конфигурирующее окно для внешнего дисплея

- (void)checkForExistingScreenAndInitializeIfPresent
{
    if ([[UIScreen screens] count] > 1)
    {
        // Associate the window with the second screen.
        // The main screen is always at index 0.
        UIScreen*    secondScreen = [[UIScreen screens] objectAtIndex:1];
        CGRect        screenBounds = secondScreen.bounds;
 
        _secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
        _secondWindow.screen = secondScreen;
 
        // Add a white background to the window
        UIView*            whiteField = [[UIView alloc] initWithFrame:screenBounds];
        whiteField.backgroundColor = [UIColor whiteColor];
 
        [_secondWindow addSubview:whiteField];
        [whiteField release];
 
        // Center a label in the view.
        NSString*    noContentString = [NSString stringWithFormat:@"<no content>"];
        CGSize        stringSize = [noContentString sizeWithFont:[UIFont systemFontOfSize:18]];
 
        CGRect        labelSize = CGRectMake((screenBounds.size.width - stringSize.width) / 2.0,
                                    (screenBounds.size.height - stringSize.height) / 2.0,
                                    stringSize.width, stringSize.height);
 
        UILabel*    noContentLabel = [[UILabel alloc] initWithFrame:labelSize];
        noContentLabel.text = noContentString;
        noContentLabel.font = [UIFont systemFontOfSize:18];
        [whiteField addSubview:noContentLabel];
 
        // Go ahead and show the window.
        _secondWindow.hidden = NO;
    }
}

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

Конфигурирование экранного режима внешнего дисплея

В зависимости от Вашего содержания Вы могли бы хотеть изменить экранный режим прежде, чем связать Ваше окно с ним. Много экранов поддерживают многократные разрешения, некоторые из которых используют различные попиксельные пропорции. Объекты на экране используют наиболее распространенный экранный режим по умолчанию, но можно изменить тот режим на тот, более подходящий для содержания. Например, при реализации игры с помощью OpenGL, ES и текстуры разработаны для экрана на 640 x 480 пикселей, Вы могли бы изменить экранный режим для экранов с более высокими разрешениями по умолчанию.

Если Вы планируете использовать экранный режим кроме по умолчанию, необходимо применить тот режим к UIScreen объект прежде, чем связать экран с окном. UIScreenMode класс определяет атрибуты единственного экранного режима. Можно получить список режимов, поддерживаемых экраном от availableModes свойство и выполняет итерации через список для того, соответствующего Ваши потребности.

Для получения дополнительной информации об экранных режимах, посмотрите Ссылку класса UIScreenMode.