Представления

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

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

Создание и конфигурирование объектов представления

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

Создание объектов представления Используя интерфейсного разработчика

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

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

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

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

Создание представления возражает программно

Если Вы предпочитаете создавать представления программно, можно сделать настолько использующий стандартный образец выделения/инициализации. Метод инициализации по умолчанию для представлений initWithFrame: метод, устанавливающий начальный размер и позицию представления относительно (скоро, чтобы быть установленным) родительское представление. Например, для создания нового обобщения UIView объект, Вы могли использовать код, подобный следующему:

CGRect  viewRect = CGRectMake(0, 0, 100, 100);
UIView* myView = [[UIView alloc] initWithFrame:viewRect];

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

Установка свойств представления

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

Таблица 3-1 перечисляет некоторые более обычно используемые свойства (и некоторые методы) и описывает их использование. Связанные свойства перечислены вместе так, чтобы Вы видели опции, которые Вы имеете для влияния на определенные аспекты представления.

Табличное 3-1  Использование некоторого ключа просматривает свойства

Свойства

Использование

alpha, hidden, opaque

Эти свойства влияют на непрозрачность представления. alpha и hidden свойства изменяют непрозрачность представления непосредственно.

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

bounds, frame, center, transform

Эти свойства влияют на размер и позицию представления. center и frame свойства представляют позицию представления относительно его родительского представления. frame также включает размер представления. bounds свойство определяет видимую предметную область представления в своей собственной системе координат.

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

Для получения информации об отношении между bounds, frame, и center свойства, посмотрите Отношение Кадра, Границ и Центральных Свойств. Для получения информации о том, как преобразовывает, влияйте на представление, смотрите Трансформации Системы координат.

autoresizingMask, autoresizesSubviews

Эти свойства влияют на автоматическое поведение изменения размеров представления и его подпредставлений. autoresizingMask свойство управляет, как представление реагирует на изменения в границах своего родительского представления. autoresizesSubviews свойство управляет, изменены ли подпредставления текущего представления вообще.

contentMode, contentStretch, contentScaleFactor

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

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

gestureRecognizers, userInteractionEnabled, multipleTouchEnabled, exclusiveTouch

Эти свойства влияют, как Ваше представление обрабатывает сенсорные события. gestureRecognizers свойство содержит устройства распознавания жеста, присоединенные к представлению. Другие свойства управляют что сенсорные события поддержки представления.

Для получения информации о том, как реагировать на события в Ваших представлениях, посмотрите Руководство по Обработке событий для iOS.

backgroundColor, subviews, drawRect: метод, layer, (layerClass метод)

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

Для более усовершенствованного содержания можно работать непосредственно с Базовой Анимацией представления layer. Для указания полностью другого типа уровня для представления необходимо переопределить layerClass метод.

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

Тегирование представлений для будущей идентификации

UIView класс содержит a tag свойство, которое можно использовать для тегирования отдельных объектов представления с целочисленным значением. Можно использовать теги, чтобы однозначно определить представления в иерархии представления и выполнить поиски тех представлений во время выполнения. (Основанные на теге поиски быстрее, чем итерация иерархии представления самостоятельно.) Значение по умолчанию для tag свойство 0.

Для поиска маркированного представления используйте viewWithTag: метод UIView. Этот метод выполняет поиск в глубину получателя и его подпредставления. Это не ищет суперпредставления или другие части иерархии представления. Таким образом вызов этого метода от корневого представления иерархии ищет все представления в иерархии, но вызов его от определенного подпредставления ищет только подмножество представлений.

Создание и управление иерархией представления

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

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

Рисунок 3-1  Многоуровневые представления в приложении Часов
Layered views in the Clock application

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

Добавление и удаление подпредставлений

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

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

  • Для добавления подпредставления к родителю вызовите addSubview: метод родительского представления. Этот метод добавляет подпредставление до конца списка родителя подпредставлений.

  • Для вставки подпредставления посреди списка родителя подпредставлений вызовите любой из insertSubview:... методы родительского представления. Вставка подпредставления посреди списка визуально помещает то представление позади любых представлений, прибывающих позже в список.

  • Для переупорядочения существующих подпредставлений в их родителе вызовите bringSubviewToFront:, sendSubviewToBack:, или exchangeSubviewAtIndex:withSubviewAtIndex: методы родительского представления. Используя эти методы быстрее, чем удаление подпредставлений и перевставка их.

  • Для удаления подпредставления из его родителя вызовите removeFromSuperview метод подпредставления (не родительское представление).

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

Наиболее распространенный пример добавления подпредставления к другому представлению происходит в application:didFinishLaunchingWithOptions: метод почти каждого приложения. Перечисление 3-1 показывает версию этого метода, устанавливающего представление от основного контроллера представления приложения в окно приложения. И окно и контроллер представления сохранены в основном файле пера приложения, загружающемся, прежде чем метод вызывают. Однако иерархия представления, которой управляет контроллер представления, фактически не загружается до view к свойству получают доступ.

Перечисление 3-1  , Добавляющее представление к окну

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
 
    // Add the view controller's view to the window and display.
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
 
    return YES;
}

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

Перечисление 3-2 показывает viewDidLoad метод TransitionsViewController класс от UICatalog: Создание и Настройка Средства управления UIKit (Obj-C и Swift) пример приложения. TransitionsViewController класс управляет анимациями, связанными с переходом между двумя представлениями. Начальная иерархия представления приложения (состоящий из корневого представления и панели инструментов) загружается из файла пера. Код в viewDidLoad метод впоследствии создает контейнерное представление, и представления изображения раньше управляли переходами. Цель контейнерного представления состоит в том, чтобы упростить код, должен был реализовать анимации перехода между этими двумя представлениями изображения. Контейнерное представление не имеет никакого реального собственного содержания.

  Добавление перечисления 3-2 просматривает к существующей иерархии представления

- (void)viewDidLoad
{
    [super viewDidLoad];
 
    self.title = NSLocalizedString(@"TransitionsTitle", @"");
 
    // create the container view which we will use for transition animation (centered horizontally)
    CGRect frame = CGRectMake(round((self.view.bounds.size.width - kImageWidth) / 2.0),
                                                        kTopPlacement, kImageWidth, kImageHeight);
    self.containerView = [[[UIView alloc] initWithFrame:frame] autorelease];
    [self.view addSubview:self.containerView];
 
    // The container view can represent the images for accessibility.
    [self.containerView setIsAccessibilityElement:YES];
    [self.containerView setAccessibilityLabel:NSLocalizedString(@"ImagesTitle", @"")];
 
    // create the initial image view
    frame = CGRectMake(0.0, 0.0, kImageWidth, kImageHeight);
    self.mainView = [[[UIImageView alloc] initWithFrame:frame] autorelease];
    self.mainView.image = [UIImage imageNamed:@"scene1.jpg"];
    [self.containerView addSubview:self.mainView];
 
    // create the alternate image view (to transition between)
    CGRect imageFrame = CGRectMake(0.0, 0.0, kImageWidth, kImageHeight);
    self.flipToView = [[[UIImageView alloc] initWithFrame:imageFrame] autorelease];
    self.flipToView.image = [UIImage imageNamed:@"scene2.jpg"];
}

Когда Вы добавляете подпредставление к другому представлению, UIKit уведомляет и родительские и дочерние представления изменения. При реализации пользовательских представлений можно прервать эти уведомления путем переопределения один или больше willMoveToSuperview:, willMoveToWindow:, willRemoveSubview:, didAddSubview:, didMoveToSuperview, или didMoveToWindow методы. Можно использовать эти уведомления, чтобы обновить любую информацию состояния, связанную с иерархией представления или выполнить дополнительные задачи.

После создания иерархии представления можно переместиться по нему программно использование superview и subviews свойства Ваших представлений. window свойство каждого представления содержит окно, в котором то представление в настоящее время выводится на экран (если таковые имеются). Поскольку корневое представление в иерархии представления не имеет никакого родителя, superview свойство установлено в nil. Для представлений, которые являются в настоящее время экранными, объект окна является корневым представлением иерархии представления.

Сокрытие представлений

Для сокрытия представления визуально можно или установить скрытый свойство к YES или изменение alpha свойство к 0.0. Скрытое представление не получает сенсорные события от системы. Однако скрытые представления действительно участвуют в автоизменении размеров и других операциях расположения, связанных с иерархией представления. Таким образом, если Вы планируете показать представления снова в некоторый момент скоро, сокрытие представления часто является удобной альтернативой удалению представлений от Вашей иерархии представления, особенно.

Если Вы хотите анимировать переход представления от видимого до скрытого (или реверс), необходимо сделать настолько использующий представление alpha свойство. hidden свойство не является animatable свойством, таким образом, любые изменения, которые Вы вносите в него, сразу вступают в силу.

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

Существует два способа определить местоположение представлений в иерархии представления:

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

  • Присвойте уникальное целое число каждому представлению tag свойство и использование viewWithTag: метод для определения местоположения его.

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

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

Перевод, масштабируясь и поворачивая представления

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

transform свойство UIView содержит a CGAffineTransform структура с трансформациями для применения. По умолчанию это свойство установлено в идентификационные данные, преобразовывают, который не изменяет появление представления. Можно присвоить новое преобразование этому свойству в любое время. Например, для вращения представления на 45 градусов Вы могли использовать следующий код:

// M_PI/4.0 is one quarter of a half circle, or 45 degrees.
CGAffineTransform xform = CGAffineTransformMakeRotation(M_PI/4.0);
self.view.transform = xform;

Применение преобразования в предыдущем коде к представлению повернуло бы то представление по часовой стрелке о его центральной точке. Рисунок 3-2 показывает, как эта трансформация посмотрела бы, если бы это было применено к представлению изображения, встроенному в приложение.

Рисунок 3-2  , Поворачивающий представление 45 градусов

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

Для получения дополнительной информации о создании и использовании аффинных преобразований, посмотрите, Преобразовывает в Кварц 2D Руководство по программированию.

Преобразование координат в иерархии представления

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

convert...:fromView: методы преобразовывают координаты от системы координат некоторого другого представления до системы локальной координаты (прямоугольник границ) текущего представления. С другой стороны, convert...:toView: методы преобразовывают координаты из системы локальной координаты текущего представления (прямоугольник границ) к системе координат указанного представления. Если Вы указываете nil как ссылочный ракурс для любого из методов, преобразования сделаны и от системы координат окна, содержащего представление.

В дополнение к UIView методы преобразования, UIWindow класс также определяет несколько методов преобразования. Эти методы подобны UIView версии за исключением того, что вместо того, чтобы преобразовать в и от системы локальной координаты представления, эти методы преобразовывают в и от системы координат окна.

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

  Преобразование рисунка 3-3 оценивает в повернутом представлении
Converting values in a rotated view

Корректировка размера и позиции представлений во время выполнения

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

Быть подготовленным к изменениям макета

Изменения макета могут произойти каждый раз, когда любое из следующих событий происходит в представлении:

  • Размер прямоугольных изменений границ представления.

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

  • Набор Базовых подуровней Анимации, связанных с изменениями слоя представления и, требует расположения.

  • Ваше приложение вынуждает расположение произойти путем вызова setNeedsLayout или layoutIfNeeded метод представления.

  • Ваше приложение вызывает расположение путем вызова setNeedsLayout метод объекта нижележащего слоя представления.

Обработка изменений макета автоматически Используя автоизменение размеров правил

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

Для каждого представления в Вашей иерархии представления, устанавливая, что представление autoresizingMask свойство к надлежащему значению является важной частью обработки автоматических изменений макета. Таблица 3-2 перечисляет опции автоизменения размеров, Вы можете примениться к высказанному мнению и описываете их эффекты во время операций расположения. Можно объединить константы с помощью операции ИЛИ или просто добавить их вместе прежде, чем присвоить их autoresizingMask свойство. При использовании Интерфейсного Разработчика для сборки представлений, Вы используете инспектора Автокалибровки для установки этих свойств.

Таблица 3-2  , Автоизменяющая размеры констант маски

Автоизменение размеров маски

Описание

UIViewAutoresizingNone

Представление не автоизменяет размеры. (Это - значение по умолчанию.)

UIViewAutoresizingFlexibleHeight

Когда высота суперпредставления изменяется, высота представления изменяется. Если эта константа не включена, высота представления не изменяется.

UIViewAutoresizingFlexibleWidth

Изменения представления width, когда изменения суперпредставления width. Если эта константа не включена, представление width не изменяется.

UIViewAutoresizingFlexibleLeftMargin

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

UIViewAutoresizingFlexibleRightMargin

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

UIViewAutoresizingFlexibleBottomMargin

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

UIViewAutoresizingFlexibleTopMargin

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

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

  Представление рисунка 3-4, автоизменяющее размеры констант маски
View autoresizing mask constantsView autoresizing mask constants

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

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

Тонкая настройка расположения представлений вручную

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

  • Скорректируйте размер и позицию любых непосредственных подпредставлений.

  • Добавьте или удалите подпредставления или Базовые Слои анимации.

  • Вынудите подпредставление быть перерисованным путем вызова setNeedsDisplay или setNeedsDisplayInRect: метод.

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

При записи кода расположения, убедиться протестировать код следующими способами:

  • Измените ориентацию своих представлений для проверки взглядов расположения, корректных во всех поддерживаемых интерфейсных ориентациях.

  • Удостоверьтесь, что Ваш код соответственно реагирует на изменения в высоте строки состояния. Когда стороны пользователя вызов, строка состояния уменьшается в размере, когда телефонный вызов активен, увеличения высоты строки состояния размера, и.

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

Изменение представлений во время выполнения

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

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

Блоки анимации являются другим общим местом для инициирования связанных с представлением изменений. Поддержка анимации, созданная в UIView класс упрощает анимировать изменения для просмотра свойств. Можно также использовать transitionWithView:duration:options:animations:completion: или transitionFromView:toView:duration:options:completion: методы для выгрузки всех наборов представлений для новых.

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

Взаимодействие с базовыми слоями анимации

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

Изменение класса уровня, связанного с целью

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

Реализация layerClass метод должен просто создать желаемое Class объект и возврат это. Например, представление, что мозаичное размещение использования имело бы следующую реализацию для этого метода:

+ (Class)layerClass
{
    return [CATiledLayer class];
}

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

Для получения дополнительной информации о различных типах расположенных на слое объектов, предоставленных Базовой Анимацией, посмотрите Базовый Ссылочный Набор Анимации.

Встраивание расположенных на слое объектов в представлении

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

Перечисление 3-3 показывает пример viewDidLoad метод от контроллера представления, создающего пользовательский расположенный на слое объект и добавляющего его к его корневому представлению. Уровень используется для отображения анимированного статического изображения. Вместо того, чтобы добавить уровень к самому представлению, Вы добавляете его к нижележащему слою представления.

Перечисление 3-3  , Добавляющее пользовательский уровень к представлению

- (void)viewDidLoad {
    [super viewDidLoad];
 
    // Create the layer.
    CALayer* myLayer = [[CALayer alloc] init];
 
    // Set the contents of the layer to a fixed image. And set
    // the size of the layer to match the image size.
    UIImage layerContents = [[UIImage imageNamed:@"myImage"] retain];
    CGSize imageSize = layerContents.size;
 
    myLayer.bounds = CGRectMake(0, 0, imageSize.width, imageSize.height);
    myLayer = layerContents.CGImage;
 
    // Add the layer to the view.
    CALayer*    viewLayer = self.view.layer;
    [viewLayer addSublayer:myLayer];
 
    // Center the layer in the view.
    CGRect        viewBounds = backingView.bounds;
    myLayer.position = CGPointMake(CGRectGetMidX(viewBounds), CGRectGetMidY(viewBounds));
 
    // Release the layer, since it is retained by the view's layer
    [myLayer release];
}

Если Вы хотите, можно добавить любое число подуровней и расположить их в иерархии подуровня. Однако в некоторый момент те уровни должны быть присоединены к расположенному на слое объекту представления.

Для получения информации о том, как работать с уровнями непосредственно, см. Базовое Руководство по программированию Анимации.

Определение пользовательского представления

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

Контрольный список для реализации пользовательского представления

Задание пользовательского представления должно представить содержание и управлять взаимодействиями с тем содержанием. Успешное внедрение пользовательского представления включает больше, чем просто рисование и обработка событий, все же. Следующий контрольный список включает более важные методы, которые можно переопределить (и способы поведения, которые можно обеспечить) при реализации пользовательского представления:

  • Определите надлежащие методы инициализации для своего представления:

    • Для представлений Вы планируете создать программно, переопределить initWithFrame: метод или определяет пользовательский метод инициализации.

    • Для представлений Вы планируете загрузиться от файлов пера, переопределить initWithCoder: метод. Используйте этот метод, чтобы инициализировать Ваше представление и поместить его в известное состояние.

  • Реализация a dealloc метод для обработки очистки любых пользовательских данных.

  • Для обработки любого пользовательского получения переопределите drawRect: метод и делает Ваше получение там.

  • Установите autoresizingMask свойство представления для определения его поведения автоизменения размеров.

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

    • Создайте те подпредставления во время последовательности инициализации своего представления.

    • Установите autoresizingMask свойство каждого подпредставления во время создания.

    • Если Ваши подпредставления требуют пользовательского макета, переопределяют layoutSubviews метод и реализация Ваш код расположения там.

  • Для обработки сенсорных событий сделайте следующее:

  • Если Вы хотите, чтобы печатная версия Вашего представления отличалась от экранной версии, реализуйте drawRect:forViewPrintFormatter: метод. Для получения дальнейшей информации о том, как поддерживать печать в Ваших представлениях, см. Рисование и Печать Руководства для iOS.

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

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

Инициализация пользовательского представления

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

Перечисление 3-4 показывает скелетную реализацию стандарта initWithFrame: метод. Это вызовы метода наследованная реализация метода сначала и затем инициализирует переменные экземпляра и информацию состояния класса прежде, чем возвратить инициализированный объект. Вызов наследованной реализации традиционно выполняется сначала так, чтобы, если существует проблема, можно прервать собственный код инициализации и возврат nil.

Перечисление 3-4  , Инициализирующее подкласс представления

- (id)initWithFrame:(CGRect)aRect {
    self = [super initWithFrame:aRect];
    if (self) {
          // setup the initial properties of the view
          ...
       }
    return self;
}

Если Вы планируете загрузить экземпляры своего пользовательского класса представления от файла пера, необходимо знать, что в iOS, загружающий перо код не использует initWithFrame: метод для инстанцирования новых объектов представления. Вместо этого это использует initWithCoder: метод, который является частью NSCoding протокол.

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

Реализация Вашего кода для прорисовки

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

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

Прежде, чем вызвать Ваше представление drawRect: метод, UIKit конфигурирует основную среду получения для Вашего представления. В частности это создает графический контекст и корректирует систему координат и область отсечения для соответствия системы координат и видимых границ представления. Таким образом, к этому времени Ваш drawRect: метод вызывают, можно начать рисовать Ваш довольный собственный компонент использования рисование технологий, таких как UIKit и Базовая Графика. Можно получить указатель на текущий графический контекст с помощью UIGraphicsGetCurrentContext функция.

Перечисление 3-5 показывает простую реализацию a drawRect: метод, рисующий красную границу 10 пикселей шириной вокруг представления. Поскольку операции рисования UIKit используют Базовую Графику для своих конкретных реализаций, можно смешать вызовы получения, как показано здесь, для получения результатов, которые Вы ожидаете.

Перечисление 3-5  метод рисования

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGRect    myFrame = self.bounds;
 
    // Set the line width to 10 and inset the rectangle by
    // 5 pixels on all sides to compensate for the wider line.
    CGContextSetLineWidth(context, 10);
    CGRectInset(myFrame, 5, 5);
 
    [[UIColor redColor] set];
    UIRectFrame(myFrame);
}

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

Другой способ улучшить производительность получения, особенно во время прокрутки, состоит в том, чтобы установить clearsContextBeforeDrawing свойство Вашего представления к NO. Когда это свойство установлено в YES, UIKIt автоматически заполняет область, которая будет обновлена Вашим drawRect: метод с прозрачным черным цветом прежде, чем вызвать Ваш метод. Установка этого свойства к NO устраняет издержки для той операции заполнения, но помещает нагрузку в Ваше приложение для заполнения, прямоугольник обновления передал Вашему drawRect: метод с содержанием.

Ответ на события

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

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

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

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

Некоторые представления, такие как метки и изображения, отключают обработку событий в целом первоначально. Можно управлять, в состоянии ли представление получить сенсорные события путем изменения значения представления userInteractionEnabled свойство. Вы могли бы временно установить это свойство в NO препятствовать тому, чтобы пользователь управлял содержанием Вашего представления, в то время как длинная работа находится на рассмотрении. Чтобы препятствовать тому, чтобы события достигли любого из Ваших представлений, можно также использовать beginIgnoringInteractionEvents и endIgnoringInteractionEvents методы UIApplication объект. Эти методы влияют на поставку событий для целого приложения, не только для единственного представления.

Поскольку это обрабатывает сенсорные события, UIKit использует hitTest:withEvent: и pointInside:withEvent: методы UIView определить, имело ли сенсорное событие место в границах высказанного мнения. Несмотря на то, что редко необходимо переопределять эти методы, Вы могли сделать так для реализации пользовательских сенсорных способов поведения для представления. Например, Вы могли переопределить эти методы, чтобы препятствовать тому, чтобы подпредставления обработали сенсорные события.

Очистка после представления

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

Перечисление 3-6  реализовывая dealloc метод

- (void)dealloc {
    // Release a retained UIColor object
    [color release];
 
    // Call the inherited implementation
    [super dealloc];
}