Введення в Size Classes Xcode 6

Введення в Size Classes Xcode 6

Привіт всім! Сьогодні хотілося б зробити невелике введення в таку штуку, як Size Classes. Вона з'явилася нещодавно разом з Xcode 6, документації по ній від самої Apple зовсім небагато.


Отже, для чого ж призначена Size Classes? Всі ми знаємо, що на підході вже iPhone 6 двома (як мінімум) різними розмірами дисплея (4,7 і 5,5), після чого розробникам ще більше доведеться заморочуватися з версткою UI для них + само собою розширення iPad "ів. У підсумку кількість всіх підтримуваних екранів буде близько 7 (маленький привіт Android). Герой сьогоднішнього дня - Size Classes - якраз і призначений для того, що б допомогти вирішити дану проблему.

Створимо тестовий приклад у Xcode 6. Вибирем SingleViewApplication, в пункті Devices ставимо Universal:

Далі вибираємо наш Main.storyboard і у вкладці File Inspector ставимо галочку навпроти Use Size Classes (якщо вона не вибрана за замовчуванням):

Тепер звернемо увагу на наш storyboard, він не зовсім такий, яким ми звикли його бачити:

Після того, як був обраний Use Size Classes, ViewController прийняв якийсь абстрактний (базовий) розмір, з позначенням wAny hAny (будь-яка висота, будь-яка ширина) про яку поговоримо трохи далі.

Трохи теорії. Кожен створений ViewController має свій UITraitCollection об'єкт (надає детальну інформацію про характеристики ViewController, доступний з iOS 8, детальніше можна почитати тут), який у свою чергу має 2 Size Class: горизонтальний і вертикальний. Кожен Size Class може мати 3 можливі значення: компактний (compact), звичайний (regular) і будь-який (any). Ці значення змінюються залежно від пристрою та його орієнтації. Тобто, програма матиме свій окремий інтерфейс для кожного ViewController ґрунтуючись на поточних Size Class.

Повертаючись до нашого wAny hAny, що ж це? Це не що інше як сітка вибору конфігурації, для роботи з певним типом пристрою, яка виглядає наступним чином:

При наведенні курсора на сітку Apple дає підказки розробнику при яких розмірах які пристрої маються на увазі. Загальна картина сітки виглядає таким чином:

Базові значення (any Width | any Height):

iPhone ландшафтний режим (compact Width | compact Height):

iPhone портретний режим (compact Width | regular Height):

iPad ландшафтний і портретний режим (regular Width | regular Height):

Потрібно звернути увагу на зелені точки посередині кожного квадрата сітки. Вони показують до яких пристроїв будуть застосовані зміни, які ви робите в даній конфігурації. Наприклад, при базових значеннях (any Width | any Height) точки показують розробнику що зміни будуть застосовані до всіх типів пристроїв. З цієї причини Apple, рекомендує робити більшу частину роботи з інтерфейсом саме в цій конфігурації.

Повернемося до нашого тестового прикладу. Як було сказано вище зараз у нашого ViewController базовий Size Class (any Width | any Height). Додамо на наш ViewController 3 простих View розміром 100 на 100, забарвивши їх у зелений колір, також додамо UILabel і UIButton шириною 600 і висотою 50 також забарвивши їх для наочності:

Додамо Constraints:

кнопці - центрування по вертикалі і горизонталі, а також Height і Wight.

трем View — Height и Wight, Horizontal space и Vertical Space. Теж саме зробимо і з UILabel.

У підсумку наш ViewController разом з Constraints матиме наступний вигляд:

Запустимо наш додаток на виконання на iPhone 5 portrait і landscape:

і iPad 2:

Як бачимо результат не дуже втішний, на iPhone 5 portrait дві в'ю вилізли незрозуміло куди, в landscape режимі з розмірами вьюх і лейблу просто біда, а їх ширина надто велика. В iPad все не так страшно, але відстань між лейблом і кнопкою занадто велика, а перша UIView розтягнулася.

Спочатку виправимо все для iPhone 5. Для початку в Size Classes виберемо (compact Width | regular Height) для портретної орієнтації:

Зауважте, що смужка вибору Size Classes стала синьою. Це говорить про те, що б ви були повнішими, оскільки на даний момент перебуваєте не в базовій конфігурації, і зміни 4х типів будуть застосовні тільки до даного типу і орієнтації пристрою. Які ж це зміни? Як було сказано, їх 4:

1) значення Constraint'ів

2) шрифти

3) увімкнення/вимкнення Constraint'ів

4) ввімкнення/вимкнення subviews

P.S. Нагадаємо, все що буде далі зроблено, застосовне ТІЛЬКИ до портретної орієнтації iPhone 5, про що нас інформує зелена точка в сітці Size Classes!

Почнемо з 1 пункту і виправимо значення Constraint, що б все виглядало коректно. У цій конфігурації ми бачимо помилки Constraint:

Для їх виправлення в даній орієнтації йдемо до налаштувань Constraint, і виберемо значення горизонтальної відстані між View так як для iPhone воно занадто велике:

На панелі Utilities у вкладці Size Inspector біля пункту Constant (а також біля «Installed», але про нього пізніше) тиснемо невеликий знак «+»:

І вибираємо «Compact Width | Regular Height (current)»:

Бачимо, що у нас з'явилася нова Constant (wC hR), для даної орієнтації, введемо значення 34. Теж саме проробляємо з другим Constraint між 2й і 3й в'ю.

Після чого у нас повинні зникнути помилки пов'язані з відстанню за шириною між в'ю:

Теж саме проробимо і з шириною кнопки і лейблу для даної орієнтації. Виберемо їх ширину, додамо Constant «Compact Width | Regular Height (current)», і встановимо значення 200:

Як ми пам'ятаємо, нашій кнопці ми встановлювали Horizontal Center in Container і Vertical Center in Container, від чого і виникають конфлікти, що залишилися. Їх можна вирішити як мінімум 2 способами залежно від того, що потрібно, 1й спосіб, розмістити кнопку по центру як вона того і вимагає, або залишити все як є і скористатися 3 пунктом зі списку вище. У даному прикладі ми скористаємося способом під номером 2, оскільки це все таки стаття про Size Classes.

Отже, для того щоб «вимкнути» Constraint, яка нам заважає, потрібно її вибрати зі списку:

І знову звернутися до вкладки Size Inspector, тільки тепер натискаємо «+» який біля чекбоксу «Installed»:

Знову таки вибираємо і вибираємо «Compact Width | Regular Height (current)», і тепер у нас як і з Constant (wC hR) з'явився чекбокс wC hR «Installed», прибираємо його і бачимо, що помилки зникли, а для даної конфігурації даний Constrain вимкнений:

Запустимо нашу програму на виконання і побачимо, що все відображається коректно (ну майже все, оскільки розміри View не підганялися для конкретного пристрою Xcode автоматично зменшує одну з них):

Дану проблему ми виправимо пізніше.

Виконуємо аналогічні дії для iPhone 5 landscape, виберемо в сітці Size Classes (compact Width | compact Height):

Нам потрібно так як і для портретного режиму змінити відстань між в'ю і розміри кнопки і лейблу, я вибрав такі ж значення як і для портретного режиму: відстань між в'ю 34, розмір кнопки і лейблу 200. Запустимо наш апп:

Знову таки через те, що ми не підганяли розмір, Xcode розтягує View. Виправимо цю помилку в портретній (compact Width | regular Height) і ландшафтній (compact Width | compact Height) орієнтації. Виділимо наші 3 вьюхи і вибираємо в меню Editor - > Pin - > Widths Equally. Після чого запустимо нашу програму на виконання і бачимо що все відображається коректно:

Щоб не повторюватися для iPad, ми проробляємо все те саме, що і для iPhone, тільки в сітці Size Classes вибираємо regular Width | regular Height, що відповідає портретній і ландшафтній орієнтації iPad. У даній ситуації ми просто оновили всі Constraint, відцентрували і виставили Width, Height Equally:

Залишилося 2 пункти, за якими не пройшлися, це включення/вимикання subviews і шрифти. Виберемо ландшафтний режим iPhone compact Width | compact Height. Виділимо наш UILabel і перейдемо в Attributes Inspector, навпроти шрифту ми побачимо вже знайомий нам «+»:

За аналогією з Constraint додаємо «compact Width | compact Height (current)». Для wC hC виставимо шрифт Helvetica Neue Ultra Light і розмір 23. При запуску ми побачимо що в портретній орієнтації шрифт стандартний а вже в ландшафті Helvetica Neue:

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

Загалом, моя перша стаття вийшла не маленька, але і невелика, сподіваюся, вона цікава і корисна. На момент написання статті Xcode 6 ще в беті, і не випущений iPhone 6, після презентації якого можливо поповниться документація, а також зміниться і зовнішній вигляд ViewController'ів в storyboard, так як в даній ситуації не дуже зручно все розміщувати в «квадратах», хоча в сітці Size Classes обраний iPhone landscape.

За матеріалами: developer.apple.com/library/prerelease/ios/recipes/xcode_help-IB_adaptive_sizes/EnablingAdaptiveSizeDesign.html#//apple_ref/doc/uid/TP40014436-CH1-SW1

Дякую за увагу!