Векторні сцени і анімації - як побороти сегментацію в iOS

Привіт, мене звати Віталій Малаховський, я інженер в компанії Genesis.

Нещодавно мені довелося попрацювати над цікавою завданням: зробити анімацію для iOS додатки, яка буде зберігати пропорції при зміні розміру (тобто бути векторної). І, звичайно, вона не повинна втрачати при цьому якість ресурсів. Порившись в інтернеті, я знайшов кілька способів зробити це:

Всі приклади роботи з ресурсами, які я вам покажу, на Zeplin. Але якщо ви не користуєтеся Zeplin — не біда. Самостійно знайдіть розміри ресурсів в будь-якій іншій зручній для вас програмі.

Векторні ресурси

Ми будемо використовувати PDF формат ресурсів — це векторний формат, тому ми можемо масштабувати їх настільки, наскільки нам потрібно, — а значить одним файлом можна користуватися для всіх дозволів. Для цього загляньте в xcassets та знайдіть потрібний файл PDF або додайте його туди відразу, якщо його там ще немає ? Перевірте, щоб було вибрано «Single Scale» в підменю «Scales» та відзначений «Preserve Vector Data». На цьому з ресурсами закінчили.

Відносні значення

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

Насамперед помістіть всі елементи в геометричну фігуру. Якщо навести вказівник миші на область поряд з зображенням, Zeplin покаже вам прямокутник/квадрат, у який воно вписано, або розміри до краю екрана. Тоді можете орієнтуватися на них. Запишіть/запам'ятайте розмір геометричної фігури в пікселях. У моєму випадку це — прямокутник 264?233.

Тепер нам потрібно знайти розміри всіх елементів і їх центральні точки відносно щойно знайденої фігури. Раджу експортувати всі елементи у вигляді окремих картинок, а потім подивитися на їх розміри, оскільки, іноді, коли ви натискаєте на зображення Zeplin, він показує розмір якійсь частині, а не зображення цілком. На прикладі видно, як Zeplin показує вилку без тіні, а на вже експортованому зображенні — вилка вже з тінню.

Далі потрібно знайти центральні точки. Якщо ви шукаєте розміри відносно краю екрана, то просто у верхньому куті ви знайдете точки Х і Y. Якщо ж ви шукаєте середину щодо фігури, в якій вписані елементи (тобто не від країв екрана), натисніть на цю фігуру, а потім наведіть мишкою на конкретну картинку, середину якого ви шукаєте. Ви побачите відстань до кордонів. Запам'ятали. Тепер додайте половину ширини до Х і половину висоти до Y. Це і є центр фігури. Знову ж таки, значення можуть бути неправильні, якщо у вас є тінь або щось подібне. Тому завжди краще звернутися до свого дизайнерові. В моєму випадку немає нічого, що може вплинути на значення.

Приклад:
Розмір мого зображення — 26?117, Х і Y — 36 та 58 відповідно.
Центр по горизонталі = Х + «ширина»/2 = 36 + 26/2 = 49.
Центр по вертикалі = Y + висота»/2 = 58 + 117/2 = ~117.
Центр = 49?117.

Layout constraints

Тепер ми можемо почати роботу з XCode. Створіть UIView, де будуть розташовуватися всі елементи. При бажанні, можете зробити розмір UIView такий же, як і у фігури, щодо якої ми міряли розміри. 264?233 — в моєму випадку.

Додайте UIImageView і встановіть їй PDF в якості зображення. Встановіть «layout constraints» для ширини і висоти, щодо супервью. Значення констант для всіх наших «layout constraints» повинні дорівнювати 0, але ось множники (multipliers) повинні виражати співвідношення між розміром межі зображення і розміром межі фігури, в яку ми вписуємо наші зображення.

На пальцях: множник для висоти виражає співвідношення висоти зображення і висоти супервью, множник для ширини — співвідношення ширини зображення і ширини супервью.

Приклад:
Розмір мого зображення — 26?117, розмір супервью — 264?233.
Множник для висоти = «висота зображення» : «висоти супервью» = 117:233.
Множник для ширини = «ширина зображення» : «ширина супервью» = 26:264.

Тепер нам потрібно встановити позицію для наших зображень. Вона теж буде у відносних величинах. Для цього ми, власне, і морочилися з центральними точками, які розрахували раніше. Встановіть «layout constraints» для зображення, щоб воно стояло рівно по центру супервью (windows horizontally in container & windows vertically in container). Значення констант повинні дорівнювати 0. Множники повинні мати наступне значення: бажаний центр осі зображення до центру осі фігури, в яку ми вписуємо зображення.

Приклад:
Бажаний центр зображення = 49?117.
Розмір супервью = 264?233, відповідно центр суперью = 132?117.
Множник по горизонталі = «центр зображення по осі Х» : «центр супервью по осі Х» = 49:132.
Множник по вертикалі = «центр зображення по осі Y» : «центр супервью по осі Y» = 117:117 або просто 1.

Приємний бонус: Interface builder динамічно перемалюють всю сцену в правильних співвідношеннях при збільшенні /зменшенні розмірів супервью, не потрібно навіть перекомпілювати код.

Анімація

Ідея, по суті, та ж: обчислювати відносні значення для зміщень по осях або змін розмірів, а потім перетворити її в скалярні значення на основі розміру супервью для анімації. Давайте проведемо розрахунки для горизонтального зміщення.

Вимоги: вилка повинна зміститися на 30 пікселів вліво. Відносне значення буде наступним: «зсув»/(ширина»/100%) = 30/(233/100) = ~13%. Щоб використовувати наш результат в коді, ми повинні помножити це відносне значення на значення ширини супіском (тобто зробити зворотне обчислення).

Приклад коду:

private func newTableClothAnimator() -> UIViewPropertyAnimator {
 return UIViewPropertyAnimator(duration: 0, curve: .easeInOut) {
 self.tableCloth.transform = CGAffineTransform(translationX: -(self.frame.width * 0.13), y: 0)
}
}

Підсумки

Короткий приклад того що вийшло ?



Якщо вам цікаво побачити програму цілком можете знайти за посиланням .

Опубліковано: 28/04/18 @ 07:14
Розділ Різне

Рекомендуємо:

Як купувати посилання в підписах на форумах
iOS дайджест #25: два роки з React Native, пишемо досліджуваний код, згадуємо основи Computer Science
Як вчити .NET: докладна інструкція для новачків і пару порад для досвідчених
Як скоротити ручне тестування і чи можна без нього обійтися
Розробник ядра та драйверів Intel — про входження в професію, "сушці" мізків і релокації в Фінляндії