3. diel - Swift UI pre rôzne displeja a Autolayout
V minulej lekcii, Tvorba UI a zoznámenie so základnými komponentmi , sme si vytvorili svoju prvú Swift aplikáciu v Xcode. Vedela však iba zobraziť textový popis alebo niektorý z ďalších ovládacích prvkov Apple, ktoré sme si minule popísali. V dnešnom tutoriále si ukážeme dôležitú súčasť tvorby UI a síce, ako zabezpečiť, aby boli komponenty na displeji presne tam, kde ich chceme.
Pravdepodobne viete, že moderné weby dnes počítajú s tým, že užívatelia majú rôzne displeja (desktop, tabliet, mobil ..) a podľa toho sa prispôsobujú. U iOS situácia nie je tak extrémne, ale stále tu máme dve veľkosti iPhone (+ nový model X), niekoľko iPadov a relevantné model je stále iPhone SE (rozmerovo rovnaký ako model 5 a 5S). Veľkosťou displeja je aj tak už veľa a mali by sme s nimi počítať.
Prácu si môžeme uľahčiť určením aplikácie len pre iPhone, predsa len podiel iPadu nie je tak veľký, ale napriek tomu musíme počítať s rôznymi displeji. Takže ako na to? Odpoveď sa volá Autolayout, čo je spôsob, ako definovať UI, aby sa prispôsobilo displeji.
Layouty
Keby mala všetky zariadenia rovnako veľké displeje, mohli by sme komponenty umiestňovať jednoducho na presné súradnice (napr. Vložiť popisok 20 pixelov na osi X a 40 pixelov na osi Y). Akonáhle sa však fyzická veľkosť zariadenia líšia, musíme ovládacie prvky na Controlleru vždy přeskládat tak, aby sa na displej všetky zmestili alebo aby naopak nevyžívaly len malú časť. Presne tento mechanizmus nám layouty prináša.
Autolayout
Prvým z layoutov, ktoré si predstavíme, je Autolayout
.
Pozícia prvkov v Autolayout určujú tzv. Constraints, čo by
sa do slovenčiny dalo preložiť ako obmedzenie. V niektorých programovacích
jazykoch je používaný pojem kotva (anchor), pretože constraints často
slúži na prichytenie nejakej strany komponenty k strane kontajnera, v ktorom
je vložená. V texte budem používať pojem constraints, pretože mi príde
výstižnejší a navyše budete poznať korektné anglický termín.
Aby Autolayout
fungovať korektne, musí mať každá komponenta
presne určené, ako má byť umiestnená vzhľadom k ďalším komponentom
alebo okrajom UI daného Controlleru. Existuje viac možností ako to docieliť.
Komponent môžeme jednoducho zarovnať na oboch osiach, definovať ju
vzdialenosť od okraja iného UI prvku a tak podobne. Všetko si podrobne
ukážeme. V rôznych situáciách sa hodia rôzne prístupy.
Autolayout
môže byť pre začiatočníkov
náročný, stále sa ale jedná o jedinú rozumnú cestu, ako UI navrhovať,
takže sa mu nevyhýbajte a nevzdávajte použitie Autolayout po niekoľkých
nevydarených pokusoch.
Praktická ukážka
Otvoríme Main.storyboard
, pokojne v tom istom projekte s
Label
em z minulej lekcie. Prípadne môžete založiť nový
projekt a nejaké UI komponenty doň pridať. Je to jedno, pracovať budeme len
v jednom súbore. Označme si napr. Label
a zarovnajte ho na stred
pomocou constraints. K tomu slúži ikonky v pravom dolnom rohu editora.
Zarovnanie komponenty
Prostredná ikonka Align constraints s dvoma obdĺžničky slúži práve k zarovnanie.
Zaškrtne Vertically in Container a Horizontally in
Container, čím Label
vycentrujeme v oboch smeroch. Potom už
stačí len kliknúť na Add 2 Constraints, čím sa k nemu
príslušná zarovnávacej obmedzenia nastaví. Pojmom container sa myslí
komponent, v ktorej je prvok vložený. V tomto prípade je myslený celý
controller. Ak by ste Label
mali napr. Vnútri komponenty
View
, ktorá sa často používa práve ako container ostatných
prvkov alebo napríklad na zaznamenanie dotykových gest, tak container bude
práve tento View
. Týmto je Label
zarovnaný a na
všetkých displejoch bude uprostred. Jeho skutočná pozícia (X a Y) sa bude
teda meniť podľa veľkosti displeja daného zariadenia.
výsledok:
Zaujíma vás, prečo sme mohli zadať tiež konkrétne číslo a v
predvolenom stave to bola 0
? To je pre prípad, že by sme
Label
chceli od stredu posunúť na ľubovoľnú stranu. Napr. o
niekoľko pixelov vertikálne nad stred. Už pridanej constraints si môžete
skúsiť editovať v Size inšpektorovi. Pretože sa súradnice počítajú od
ľavého horného rohu, náš Label
by sme posunuli nahor napr.
Nastavením CONSTRAINT pre Y os na -30
.
Pripnutie k stranám a obmedzenia veľkosti
Align constraints sa hodí najmä k centrovanie. Teraz si ukážeme
CONSTRAINT na pozíciu a veľkosť. Tu už platí, že musíte mať nastavené
buď constraints pre všetky štyri strany alebo dve strany + šírku a výšku
komponenty. (Aby som bol kompletný, tak výške sa môžete vyhnúť cez
Aspect ratio.) Jedine tak bude Autolayout
presne vedieť, kam
komponent umiestniť a akú veľkosť ju nastaviť. Samozrejme nemôžete mať
nastavené napr. Constraints pre ľavú a pravú stranu a zároveň nastaviť
fixné šírku. Tieto constrains budú medzi sebou v konflikte, pretože
prichytením oboch strán komponenty ku kontajneru sa komponent bude samozrejme
s kontajnerom rozťahovať do šírky.
Skúsime si teraz náš Label
umiestniť do pravého horného
rohu. Označte ho a následne kliknite na ikonku vedľa tej zarovnávaciu,
ktorá vyzerá trochu ako Tie Fighter.
Tento dialóg už vyzerá komplikovanejšie, ale nie je sa čoho desiť. Chceme pravý horný roh, takže budeme zarovnávať od hornej a pravej hrany. Odporúčam odškrtnúť Constrain to margins, ktoré počíta od akýchsi vnútorných hrán a občas nefunguje korektne. Osobne sa mi často stáva, že tieto margins nie sú registrované a navyše, keď ich nikdy nebudete používať, nestane sa vám, že by ste sa pomýlili v rozmeroch pod.
Label
umiestnime napr. 40
pixelov od hornej hrany a
40
pixelov od pravej. To, že je CONSTRAINT aktívna spoznáte
podľa neprerušované červenej čiary. Po kliknutí sa aktivuje / deaktivuje a
rovnako tak ho aktivuje zadanie novej hodnoty. Pretože sme Label
ukotvili k hornej a pravej hrane, nezabudnite nastaviť i šírku a výšku,
inak by nebola jeho veľkosť definovaná. Potom už stačí len kliknúť na
Add 4 Constraints a Label
sme úspešne ukotvili. V pravom
hornom rohu teraz zostane. Vyskúšať to môžete proklikáním rôznych
displejov - prepínač je v dolnej časti editora.
Týmto sme dva základné prístupy prebrali, tým Autolayout
však zďaleka nekončí.
Viac komponentov
Akonáhle máme v kontajneri viac komponentov, Autolayout
je pri
tvorbe constraints zohľadní. Ak by sme teraz k nášmu Label
u v
pravom hornom rohu pridali na jeho ľavú stranu ďalšie komponent, napr.
Tlačidlo Button
, CONSTRAINT vzdialenosti pre pravú hranu
tlačidla sa bude počítať od Label
u, čo dáva zmysel. Môžete
si ale zvoliť, aby sa opäť počítal od hrany Controlleru (šípka dole v
poli pre hodnotu). To ale neodporúčam.
Než takto začnete nastavovať constraints viac prvkom, oplatí sa
popremýšľať, ako má výsledok vyzerať a či treba nebudete v blízkej dobe
pridávať komponenty alebo meniť ich umiestnenie. Nebojte sa využívať
obyčajný View
ako kontajner pre komponenty, ktoré patria k sebe.
Constraints potom budete nastavovať od hrán tohto View
a ten
samotný potom ľahko posuniete. Pokojne jednotlivým View
dočasne
nastavte výrazné farby pozadia, nech máte prehľad, ako sú umiestnené.
Konflikt medzi constraints
Občas sa vám stane, že Autolayout
začne
"nadávať", pretože mu constraints nesedí. Vtedy ste buď zabudli
nastaviť všetko požadované alebo omylom pridali duplicitné CONSTRAINT.
Button
napr. Nemôže byť 0
od ľavého okraja a
zároveň iným CONSTRAINT nastavený na 20
taktiež od ľavého
okraja. Xcode vám pomerne dobre ukáže, kde je problém a umožní opravu
"jedným klikom". Osobne tieto jednoduché opravy nevyužívam,
pretože často skončí inak, než by som si prial. Rovnako tak veľmi zriedka
používam Reset to suggested constraints, ktoré constraints určí za
vás. Možno vám tieto možnosti vyhovovať budú, stačí ich vyskúšať.
Pripomínam, že constraints nájdete v Size inšpektorovi jednotlivých
komponentov.
V budúcej lekcii, Jednoduchá kalkulačka pre iOS vo Swift , sa pozrieme konečne na niečo praktického a
vytvoríme jednoduchú iOS kalkulačku. S ňou sa naučíme používať
StackView
a prepojiť UI s kódom.