Параллакс в седьмой версии операционной системы. Параллакс в седьмой версии операционной системы Эффект параллакса iphone

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

А начнем мы с панорамных обоев в iOS 7. А точнее с их отсутствия…

Панорамные обои в iOS 7

Панорамные обои появились в iOS 7 beta 1 . Эта функция позволяла установить панорамные фотографии (примеры панорам есть на нашем форуме) в качестве обоев на рабочий стол или экран блокировки. Пользователи вертели в руках устройство на iOS 7 и на экране фотография перемещалась в зависимости от того, под каким углом в данный момент находится устройство.

В iOS 7 beta 6 по каким-то своим причинам компания Apple убрала этот функционал из прошивки. Именно поэтому в финальной версии iOS 7.0 функции “Панорамные обои” НЕТ!

Вы, конечно, можете установить панорамы вместо обоев. Система позволит это сделать, но “того самого” эффекта это не даст. Вы увидите только Параллакс эффект.

Параллакс эффект в iOS 7

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

Теперь, когда я пояснил принцип работы параллакс эффекта в iOS 7, становится очевидным, что такие понятия, как “Параллакс обои” или “Обои с эффектом параллакс” с точки зрения русского языка и понимания процесса, ошибочны и только вводят пользователей в заблуждение. Так называемые “Параллакс обои” – это не что иное, как обычные стандартные обои, которые отличаются только лишь разрешением.

Достаточно сохранить фотографию в нужном разрешении, залить её в iPad, iPhone или iPod Touch и она будет иметь эффект параллакса в iOS 7. Если этого не сделать или воспользоваться обоями, которые создавались для iOS 6, то возможен неприятный эффект растягивания изображения из-за которого многие наши читатели не могли спать спокойно.

Разрешения для снимков, если вы хотите параллакс эффект в обоях (в скобках стандартное рекомендуемое разрешение для снимков без параллакс эффекта в iOS 6 и ниже):

iPad 2 1424 х 1424 (1024 x 1024)

iPad Mini 1424 х 1424 (1024 х 1024)

iPad 3 2448 х 2448 (2048 х 2048)

iPad 4 2448 х 2448 (2048 х 2048)

iPhone 4S 1360 х 1040 (960 х 640)

iPhone 5, 5S, 5C 1536 на 1040 (1136 х 640)

iPod Touch 5Gen 1536 на 1040 (1136 х 640)

iPhone 4 не поддерживает параллакс эффект (960 х 640)

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

Как самостоятельно сделать обои?

Самостоятельно сделать обои хоть с параллакс эффектом, хоть без него очень легко.

На нашем сайте давно есть пошаговая инструкция на примере Photoshop – Как сделать обои для iPad . Инструкция не потеряла актуальности и сейчас. Главное выбрать правильное разрешение для вашего устройства (рекомендуемое разрешение чуть выше в этой статье).

После того, как картинка в нужном разрешении создана, вы можете:

1) отправить её самому себе на почту и потом сохранить в фотопленку

Как отключить Параллакс эффект в iOS 7?

Некоторым пользователям не нравится параллакс эффект. Отключить его можно в настройках.

Настройки->Основные->Универсальный доступ->Уменьшение движения. Включить переключатель “Уменьшение движения”.

Динамичные обои в iOS 7

В iOS 7 появились встроенные в систему динамичные обои. Некоторые называют их “живые” или “динамические”. Но Apple сказала Динамичные, а значит мы будем придерживаться официальной терминологии.

Установить их можно в настройках (Настройки->Обои и яркость->Выбор обоев->Динамичные ). По типу Динамичные обои друг от друга отличаются только цветом. Сейчас на выбор есть 7 цветов.

На всех обоях в режиме реального времени движутся/уменьшаются/увеличиваются/меняют прозрачность шарики (про любовь Apple к шарикам все уже знают).

Собственные уникальные динамичные обои для iOS 7 сделать сейчас официально нельзя! Пользуйтесь тем, что есть. В будущем есть вероятность появления способов установки своих динамичных обоев.

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

Панорамные картинки в «семёрке»

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

В шестой бета по каким-то причинам убрала такой эффект из iOS 7. Именно поэтому у оригинальной чистой iOS 7 нет такой функции, как панорамы. Вы, конечно, удивитесь и спросите: «А где они есть?». Их заменил параллакс эффект. Конечно, можно поставить панорамы, но того самого эффекта вы не увидите, который присутствовал в iOS 7 beta 1.

Параллакс эффект

А теперь давайте взглянем на параллакс. Это отлично нововведение, которое позволяет иконкам и обоям на рабочем экране жить отдельной жизнью друг от друга. Обои находятся в одной плоскости, а иконки – в другой. Гаджет на iOS 7 считывает информацию с гироскопа и перемещает эти две плоскости относительно друг друга так, что в результате перемещения мы видим те части изображение, которые до этого были «за кадром». За счет этих манипуляций у пользователя возникает ощущение глубины и многомерности.

Когда мы объяснили, что такое параллакс эффект и как он работает в iOS 7, становится понятным, что такие определения, как «Панорамные обои» или «Обои с параллаксом» вводят юзеров в заблуждение. Ведь с точки зрения понимания процесса и русского языка, это разные функции, на деле же – совершенно одинаковое действие. Так называемые «Панорамные обои» — это не что иное, как простые фото, которые отличаются от других изображений только своим разрешением.

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

Разрешения для фото, если вы хотите получить параллакс эффект на рабочем экране (в скобках мы указали стандартное рекомендуемое разрешение для фото без параллакс с шестой версии iOS):

  • Планшет Айпад 2 - 1424 х 1424 (1024 x 1024)
  • Айпад Мини - 1424 х 1424 (1024 х 1024)
  • Айпад 3 - 2448 х 2448 (2048 х 2048)
  • Айпад 4 - 2448 х 2448 (2048 х 2048)
  • Айфон 4S - 1360 х 1040 (960 х 640)
  • Айфон 5, 5S, 5C -1536 на 1040 (1136 х 640)
  • Айпод 5 поколения - 1536 на 1040 (1136 х 640)
  • Айфон 4 - не поддерживает parallax (960 х 640)

Уже сейчас множество людей занимаются созданием разнообразных коллекций с такими заставками, есть даже приложения «Динамичные и parallax заставки», через которые можно скачивать новые картинки. Но мы теперь знаем, что все прощё, чем кажется. Такие приложения – это очередная попытка срубить денег.

Как самому сделать картинки с таким эффектом?

Сделать можно все при помощи редактора изображений. Самый популярный вариант – это, конечно же, Photoshop. Главное, что нужно будет сделать – это выбрать правильное разрешение, подходящее под ваш гаджет (выше мы написали все разрешения под все устройства). После того, как у вас есть изображение с нужным разрешением, вам нужно будет залить его на устройство одним из этих способов:

  1. Отправить картинку самому себе на электронную почту, а затем сохранить на фотопленку;
  2. Закачать на Dropbox и снова сохранить в фото галерею;
  3. Закачать по стандартной схеме через iTunes.
Как выключить параллакс?

Некоторым юзером это нововведение не нравится. Отключить его можно в настройках. Настройки, затем «Основные», затем «Универсальный доступ», потом «Уменьшение движения». Нажимаем на переключатель «Уменьшение движения» — этим нажатием можно отключить праллакс.

Динамичные изображения

В обновлениях iOS 7 появились динамичные фото. Динамичные изображения можно установить в настройках. Заходим в Настройки, там находим вкладку «Обои и яркость», затем находим там «Выбор обоев» — Динамичные. Отличаются динамичные изображения друг от друга только цветом. На данный момент Apple предлагает только 7 вариантов. Динамичные изображения позволяют в реальном времени двигаться/менять прозрачность/уменьшаться элементам обоев.

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

Объяснить, что такое параллакс в iOS, проще всего цитатой из официальной презентации Apple: «iOS 7 создает ощущение многомерности. Операционная система по максимуму использует технологии iPhone, iPad и iPod touch, чтобы ещё больше расширить возможности iOS. Чёткие и функциональные слои создают глубину и упорядочивают контент. Полупрозрачный фон даёт ощущение связи с контекстом и местом. А новый подход к анимации и движению делает самые простые задачи намного более увлекательными».

Другими словами, параллакс создает иллюзию 3D-глубины экрана. Итак, чтоже нужно сделать, чтобы отключить параллакс?

  1. Заходим в меню «Настройки»;
  2. Далее – «Основные»;
  3. Выбираем «Универсальный доступ»;
  4. Затем – уменьшение движения.

После этих действий пользователь будет видеть обычный плоский экран, и никакие 3D-эффекты не подорвут его здоровье.

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

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

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

Что такое уменьшение движения в iOS?

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

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

Со временем также стали появляться улучшенные анимации открывания приложений. Также улучшались анимации переходов и много другое.

Если пользователю это просто ни к чему, то все это дело можно отключить при помощи функции «Уменьшение движения». Что также, поможет сэкономить немного заряд аккумулятора.

О ее включении мы поговорим чуть позже, а пока хочу перечислить, что именно отключится после активации:

  • убирается анимация в стандартном приложении «Погода»;
  • полностью меняются все эффекты экрана;
  • эффект параллакса, то что я объяснял про обои, тоже отключается;
  • ну и некоторые другие стандартные приложения, тоже перестают использовать анимацию.

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

Как включить/выключить уменьшение движения на айфоне?

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


Это означает, что ее используют для увеличения продолжительности работы iPhone и если у вас старая модель и вы не хотите видеть плавную работу своего устройства на последних iOS.

Ну и теперь можно приступать к включению функции уменьшение движения:

  1. как и всегда, заходим в Настройки — ищем пункт Основные ;
  2. заходим в Универсальный доступ Уменьшение движения ;
  3. видим пункт с аналогичным названием и просто активируем его, чтобы загорелось зеленым.


Внизу вы могли заметить еще один пункт, который называется «Эффекты сообщений (авто)». Лучше всего, чтобы она оставалась активной.

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

Я сейчас пользуюсь айфонов 5S и я ее активировал, как только перешел на iOS 10. Сначала конечно непривычно, но потом нормально и работать стало гораздо комфортнее.

Идея использования параллакса в дизайне мобильных приложений не нова. Как и многие другие, она пришла к нам из мира веб-дизайна, где поначалу стала очень распространённым направлением. Параллакс придаёт дизайну впечатляющий эффект глубины и кажущийся объём. К настоящему моменту в силу некоторых неудобств, связанных со спецификой разработки веб-приложений, мода на параллакс в оформлении сайтов поутихла. Однако мобильные приложения - это совсем другой разговор. Параллакс в мобильном дизайне живёт и пока не собирается никуда уходить, и даже добавлен по-умолчанию в дизайн новой iOS 7 !

В этой статье мы расскажем вам о нашем компоненте DVParallaxView , и продемонстрируем на примере его устройства, как добавить в приложение точно такой же эффект параллакса, как и в home screen в iOS 7. И даже лучше.

Как устроен параллакс?

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

Итак, как работает параллакс? Суть его довольно проста. Параллакс - это изменение положения одного и того же объекта, наблюдаемого с двух разных точек в пространстве. Понаблюдать этот эффект в реальном мире можно в любой момент. Всё, что вам понадобится - это нечто большое на роль фона (например, стена дома) и некий наблюдаемый на этом фоне объект, стоящий к вам ближе, чем фон (например фонарный столб или дерево). Если вы будете идти вдоль стены, наблюдая при этом за фонарным столбом, то вам будет казаться, что фонарный столб смещается относительно стены. Такой эффект и называется параллаксом - кажущееся смещение столба относительно стены при перемещении точки наблюдения, то есть вас. При этом чем ближе к вам будет столб, тем выше будет казаться скорость его смещения. И наоборот, если вы отойдёте от столба на значительное расстояние и попробуете пройтись вдоль стены дома опять - столб практически не будет смещаться относительно стены. Наши глаза приучены оценивать расстояние до объектов по многим признакам, и один из них - это относительная скорость смещения объекта. Если вы наблюдаете сцену, в которой объекты при вашем движении смещаются с разной скоростью - ваши глаза сразу говорят вашему мозгу, что объекты находятся на разном расстоянии от вас. В этом и заключается привлекательность использования эффекта параллакса в дизайне - сымитировав его, вы придадите плоской сцене глубину.

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

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

При наличии всех трёх основных моментов - фона, объектов и относительного движения - мы будем наблюдать параллакс.

Parallax scrolling

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

Самым очевидным подходом к реализации параллакса является parallax scrolling. Играли в старенькие игры-платформеры? Если да - то скорее всего сможете вспомнить, что пока персонаж бежал из левого конца уровня в правый, объекты на заднем плане смещались в обратном направлении с разной скоростью в зависимости от предполагаемой дальности от переднего плана. Вот ссылка на википедию , чтобы вы точно вспомнили, о чём идёт речь.

Parallax scrolling в играх был устроен таким образом, что сцена, которую вы наблюдаете на экране, состоит из нескольких слоёв, на которых расположены объекты. В зависимости от предполагаемого расстояния слоя от экрана (слой «лес» ближе к вам, чем слой «облака», которые ближе к вам, чем слой «солнце») слои смещаются с той или иной скоростью. Это придаёт происходящему на экране определённую глубину, заставляя плоскую картинку выглядеть объёмнее. Нельзя не признать - такой подход довольно хорошо соотносится с тем, что мы узнали о параллаксе. Действительно, можно мысленно разбить пространство между вами и фоном на слои, содержащие объекты, находящиеся в этом пространстве.

Логично предположить, что реализация эффекта параллакса должна быть инкапсулирована в некий компонент-контейнер, вмещающий в себя другие компоненты и имеющий некую иерархию видов, положение которых будет смещаться на расстояние, зависимое от положения в иерархии. Давайте задумаемся, а нет ли элемента в UIKit, который уже содержит в себе подобную возможность? Конечно есть! Любой UIView содержит в себе иерархию других UIView, помещённых в него методом addSubview:.

Здесь мы подходим к основной идее, положенной в основу нашего компонента DVParallaxView. Идея заключается в том, чтобы компонент был потомком UIView, инкапсулирующим в себе эффект параллакса. Сам эффект будет реализовываться передачей нового значения свойству contentOffset, имеющему тип CGPoint. Таким образом, DVParallaxView по своему смыслу является схожим с UIScrollView. При изменении значения contentOffset мы будем изменять расположение каждого view, находящегося в иерархии DVParallaxView. Величина смещения будет в обратной зависимости от удалённости элемента от «верха» иерархии. А так как элементы в массиве subviews хранятся начиная с самого нижнего в иерархии (то есть с самого дальнего от экрана), то смещение будет находиться в прямой зависимости от индекса обрабатываемого элемента при прямом проходе по массиву. Таким способом мы интерпретируем наличие «расстояния» между элементами, как в реальном мире. Для контроля величины расстояния мы выведем во внешний интерфейс свойство, представляющее собой множитель, на который будет умножаться индекс элемента в массиве. Задавая его, вы всегда сможете подстроить величину параллакса по своему желанию.

Ну что ж, предложенная модель выглядит жизнеспособной, все основные моменты продуманы. Здесь мы можем поставить точку в знакомстве с концептуальным устройством параллакса в DVParallaxView и начать рассказ о его практической реализации.

Создаём DVParallaxView

В этой и следующей главах мы подробно рассмотрим создание компонента DVParallaxView.

Перед тем, как приступить непосредственно к реализации, давайте определимся ещё с парой свойств класса DVParallaxView.

Во-первых, параллакс лучше всего выглядит и чаще всего делается на фоне какой-нибудь красивой картинки (помните, мы определились, что одной из обязательных составляющих параллакса является фон?). Поэтому в нашем классе необходимо предусмотреть возможность задать фоновое изображение. В самом корне иерархии видов всегда будет находиться приватный элемент класса UIImageView, который мы назовём backgroundImageView. Этот элемент будет исполнять роль фона в DVParallaxView. Его расположение в корне иерархии будет гарантировать нам самое малое относительное смещение, как и полагается фоновому, самому дальнему объекту сцены. Для передачи фонового изображения в публичном интерфейсе компонента будет специальное свойство - backgroundImage класса UIImage.

Во-вторых, эффект параллакса в iOS 7 складывается не только из смещения заднего фона. Если присмотреться получше, то можно заметить одну любопытную деталь: иконки смещаются в сторону, противоположную смещению фона. Сделано это для усиления эффекта параллакса и контраста между смещающимся фоном и иконками приложений, которые на первый взгляд неподвижны. Так как мы задались целью догнать и перегнать параллакс в iOS 7, то мы просто обязаны добавить такую возможность в наш компонент. Для этого мы заведём в публичном интерфейсе свойство frontView, в которое будем передавать тот вид, который мы хотим смещать в противоположную от параллакса сторону.

Итак, все приготовления сделаны - теория изучена, устройство компонента продумано. Можно приступать к созданию DVParallaxView. Готовы?

Создайте single-view проект в XCode, задайте ему имя и прочие необходимые атрибуты. Внутри проекта создайте класс DVParallaxView, который является потомком класса UIView. Создайте заголовочный файл DVParallaxView и заполните его следующим образом.

#import @interface DVParallaxView: UIView @property (nonatomic, strong) UIImage *backgroundImage; @property (nonatomic, strong) UIView *frontView; @property (nonatomic) float parallaxDistanceFactor; @property (nonatomic) float parallaxFrontFactor; @property (nonatomic) CGPoint contentOffset; @end

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

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

@interface DVParallaxView() @property (nonatomic, strong) UIImageView *backgroundImageView; @end

Пусть объект класса создаётся вызовом метода initWithFrame:. В его вызове нужно выполнить всю начальную конфигурацию.

- (id)initWithFrame:(CGRect)frame { self = ; if (self) { self.parallaxDistanceFactor = 2.f; self.parallaxFrontFactor = 20.f; self.backgroundColor = ; ; UIPanGestureRecognizer *panRecognizer = [ initWithTarget:self action:@selector(panHandler:)]; ; } return self; }

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

Если вы уже задавались вопросом «Как же мы будем инициировать смещение видов в компоненте?», то ответ на него вы уже можете увидеть в коде инициализатора — UIPanGestureRecognizer. Да, мы помним, что в iOS 7 параллакс вызывался наклоном телефона. Всему своё время.

В UIPanGestureRecognizer был передан селектор метода panHandler:. Давайте сразу напишем этот метод, чтобы не забыть сделать это потом.

#pragma mark - Gesture handler - (void)panHandler:(UIPanGestureRecognizer *)pan { CGPoint translation = ; ; ; }

Ничего необычного. Считываем перемещение касания, и такую же величину смещения задаём нашему DVParallaxView. Не забываем в конце обнулить полученное смещение.

Теперь самое интересное. Пока что по изменению contentOffset ничего не происходит, давайте это исправим. Создайте метод сеттера setContentOffset, как показано ниже.

-(void)setContentOffset:(CGPoint)contentOffset { BOOL backgroundReachedEdgeX = NO; BOOL backgroundReachedEdgeY = NO; double contentDivider; //1 if (self.backgroundImageView) { contentDivider = self.subviews.count*self.parallaxDistanceFactor; CGPoint newCenter = CGPointMake(self.backgroundImageView.center.x + (contentOffset.x - _contentOffset.x)/contentDivider, self.backgroundImageView.center.y - (contentOffset.y - _contentOffset.y)/contentDivider); if ((newCenter.x - self.backgroundImageView.frame.size.width/2.f) > 0.f || (newCenter.x + self.backgroundImageView.frame.size.width/2.f) < self.bounds.size.width) { newCenter.x = self.backgroundImageView.center.x; backgroundReachedEdgeX = YES; } if ((newCenter.y - self.backgroundImageView.frame.size.height/2.f) > 0.f || (newCenter.y + self.backgroundImageView.frame.size.height/2.f) < self.bounds.size.height) { newCenter.y = self.backgroundImageView.center.y; backgroundReachedEdgeY = YES; } self.backgroundImageView.center = newCenter; } // //2 for (int i = 1; i

Итак, разберёмся в методе поподробнее. Переменные backgroundReachedEdgeX и backgroundReachedEdgeY служат для сигнала о том, что смещая задний фон мы достигли края картинки. Если задний фон задан, то имеет смысл проверять, не вышли ли мы за пределы изображения backgroundImage. Ведь нам вовсе не хочется, чтобы пользователи созерцали «обрыв» изображения, это выглядит неестественно. Поэтому мы посчитали нужным ограничить область параллакса размерами изображения заднего фона, если оно имеется. Таким образом, блок //1 содержит в себе проверку на выход за пределы изображения.

Блок //2 - это проход по всем элементам иерархии видов с расчётом величин смещения их центров в зависимости от положения в иерархии. Также, если по осям X или Y мы находимся у края картинки заднего фона, то смещения по этим осям не произойдёт.

Основная логика смещения создана, осталось немного - задать методы доступа к основным свойствам, а также перегрузить метод addSubview.

#pragma mark - Getters -(UIImageView *)backgroundImageView { if (!_backgroundImageView) { _backgroundImageView = [ init]; _backgroundImageView.contentMode = UIViewContentModeCenter; _backgroundImageView.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); } return _backgroundImageView; } #pragma mark - Setters -(void)setParallaxDistanceFactor:(float)parallaxDistanceFactor { _parallaxDistanceFactor = MAX(0.f, parallaxDistanceFactor); } -(void)setParallaxFrontFactor:(float)parallaxFrontFactor { _parallaxFrontFactor = MAX(0.f, parallaxFrontFactor); } -(void)setBackgroundImage:(UIImage *)backgroundImage { _backgroundImage = backgroundImage; ; CGPoint origin = CGPointMake(CGRectGetMidX(self.bounds) - backgroundImage.size.width/2.f, CGRectGetMidY(self.bounds) - backgroundImage.size.height/2.f); self.backgroundImageView.frame = (CGRect){.origin = origin, .size = backgroundImage.size}; } -(void)setFrontView:(UIView *)frontView { _frontView = frontView; ; } #pragma mark - Overriding -(void)addSubview:(UIView *)view { if (self.frontView) ; else ; }

Давайте по порядку. С геттером для backgroundImageView всё понятно - обыкновенное lazy instantiation, создаём объект только при надобности. При задании значений ParallaxDistanceFactor и ParallaxFrontFactor автоматически выполнится проверка на отрицательные значения. Сеттер для backgroundImage задаёт изображение заднего фона в backgroundImageView и одновременно центрирует его положение на экране. Сеттер frontView одновременно добавляет frontView в иерархию подвидов, таким образом нет смысла добавлять его вручную. Наконец, перегруженный метод addSubview: работает в обычном режиме, если в DVParallaxView не определён frontView, но если он определён, то любой вид будет на позицию ниже него в иерархии. Ведь подразумевается, что frontView всегда впереди.

Пока что остановимся на этом и переключимся на главный viewController нашего тестового проекта. Настало время подключить наш новый компонент и проверить его в деле. Так как мы хотим быть похожими на новый home screen в iOS 7, то в тестовом проекте мы попытаемся воссоздать именно его. Для этого нам нужны картинка заднего фона (желательно с изображением космоса) и иконки приложений. Более того, так как наш компонент поддерживает и другие объекты между фоном и передним планом, то мы добавим их тоже. Раз фоном является космос, то мы разовьём космическую тему и немного оживим пустынное космическое пространство планетой Земля и её спутником - Луной. Все необходимые изображения вы можете найти в интернете или забрать из нашего тестового проекта на github .

В iOS 7 иконки приложений являются передним планом, поэтому в DVParallaxView мы должны разместить их в frontView. Для этого мы создадим UIView, в который поместим все иконки. Чтобы не заниматься вручную созданием и размещением всех этих компонент, создайте контейнер и иконки в storyboard’е, затем подключив их к контроллеру.

Вот так выглядит фронтальный вид в нашем тестовом приложении. Привяжите UIView-контейнер как IBOutlet к контроллеру и назовите его frontView. Давайте приступим к созданию экземпляра DVParallaxView.

Создайте свойство parallaxView в приватном интерфейсе вашего контроллера. Для этого свойства создайте геттер.

-(DVParallaxView *)parallaxView { if (!_parallaxView) { _parallaxView = [ initWithFrame:self.view.bounds]; [_parallaxView setBackgroundImage:]; UIImageView *earth = [ initWithImage:]; earth.frame = (CGRect) {.origin = CGPointMake(CGRectGetMidX(self.view.bounds) - earth.image.size.width/2.f, CGRectGetMidY(self.view.bounds) - earth.image.size.height/2.f), .size = earth.frame.size}; [_parallaxView addSubview:earth]; UIImageView *moon = [ initWithImage:]; moon.frame = (CGRect) {.origin = CGPointMake(CGRectGetMidX(self.view.bounds) + 30.f, CGRectGetMidY(self.view.bounds) + 30.f), .size = moon.frame.size}; [_parallaxView addSubview:moon]; [_parallaxView setFrontView:self.frontView]; } return _parallaxView; }

В коде видно, как после создания экземпляра класса DVParallaxView ему задаётся фон «galaxy2», затем в иерархию видов добавляются изображения Земли и Луны. Затем в качестве переднего плана задаётся свойство frontView. Теперь всё, что нам остаётся, это добавить наш компонент в иерархию видов контроллера. Добавьте эту строку в метод viewDidLoad:

;

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

Осталась только одна деталь. Пока что смещение элементов выполняется касаниями. Пора это поправить. Пришло время подключить к DVParallaxView гироскоп.

Подключаем Core Motion

Если вы читали нашу статью , то уже имеете все необходимые навыки для использования гироскопа в этом проекте, а также знаете, что для подключения гироскопа необходимо добавить к проекту фреймворк Core Motion. Но как именно мы будем использовать данные с датчика? В нашем проекте мы выбрали rotationRate для индикации наклонов телефона. То есть contentOffset будет изменяться при наличии ненулевой угловой скорости поворота.

Подключите фреймворк к файлу реализации класса DVParallaxView.

#import

Затем создайте свойства motionManager и displayLink в приватном интерфейсе класса.

@property (nonatomic, strong) CMMotionManager *motionManager;

@property (nonatomic, strong) CADisplayLink *displayLink;

CMMotionManager - это основной класс CoreMotion, используемый для доступа к данным с датчиков. CADisplayLink - таймер, работающий с частотой обновления экрана, который будет вызывать метод обновления данных с гироскопа.

Теперь добавим методы доступа для новых свойств.

-(CADisplayLink *)displayLink { if (!_displayLink) { _displayLink = ; } return _displayLink; } -(CMMotionManager *)motionManager { if (!_motionManager) { _motionManager = [ init]; _motionManager.deviceMotionUpdateInterval = 0.03f; } return _motionManager; }

Очевидно, что разработчику, использующему компонент DVParallaxView, совсем необязательно всегда понадобится использовать гироскоп. Возможно, будут и иные условия и действия для изменения значения contentOffset. Поэтому компонент должен предоставлять возможность выбора, нужно ли управлять параллаксом через гироскоп. Для предоставления этого выбора мы выведем в публичный интерфейс свойство gyroscopeControl, которое будет иметь тип BOOL. Если оно установлено в YES, компонент начинает считывать показания с гироскопа и смещать элементы иерархии при наклоне устройства. Если оно установлено в NO, то компонент прекращает реагировать на изменения угловой скорости устройства. При этом свойства motionManager и displayLink должны прекращать свою деятельность, чтобы не отнимать впустую ресурсы процессора.

Как мы и условились, создайте в публичном интерфейсе свойство gyroscopeControl.

@property (nonatomic, strong) BOOL gyroscopeControl;

Затем создайте для него сеттер.

-(void)setGyroscopeControl:(BOOL)gyroscopeControl { if (_gyroscopeControl == gyroscopeControl) return; _gyroscopeControl = gyroscopeControl; if (gyroscopeControl) { ; forMode:NSDefaultRunLoopMode]; } else { ; ; self.motionManager = nil; } }

Отметьте, что при установке свойства в YES motionManager начинает получать показания с deviceMotion, а не с gyroscope. Причины такого выбора подробно описаны в статье . При установке его в NO, получение данных останавливается, displayLink удаляется со всех потоков вызовом метода invalidate, а сам motionManager устанавливается в nil.

Теперь нам осталось только написать метод преобразования данных с гироскопа в данные для contentOffset, а также реализовать метод displayLinkHandler, который вызывается в таймере displayLink.

#pragma mark - Gyroscope to offset - (CGPoint)contentOffsetWithRotationRate:(CMRotationRate)rotationRate { double xOffset = (fabs(rotationRate.y) > DV_ROTATION_THRESHOLD)?rotationRate.y*DV_ROTATION_MULTIPLIER:0.f; double yOffset = (fabs(rotationRate.x) > DV_ROTATION_THRESHOLD)?rotationRate.x*DV_ROTATION_MULTIPLIER:0.f; CGPoint newOffset = CGPointMake(self.contentOffset.x + xOffset, self.contentOffset.y + yOffset); return newOffset; } - (void)displayLinkHandler { ]; }

Не забудьте в самом начале файла реализации описать две define-константы, которые мы использовали в работе метода преобразования.

#define DV_ROTATION_THRESHOLD 0.1f

#define DV_ROTATION_MULTIPLIER 2.5f

В классе контроллера при создании объекта DVParallaxView задайте его свойство gyroscopeControl в YES.

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

Заключение

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

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