In Stap 5 uit deze serie gaan we aan de slag met Auto Layout.
Ik ben in 5 stappen een app aan het maken! @iosacademie #iosdev Klik om te TweetenIn deze serie van vijf artikelen leer je, met de gratis Xcode-app voor je Mac, zelf een app maken voor je iPhone. Je maakt niet alleen kennis met Xcode; ook een aantal aspecten van App-ontwerp komt aan de orde.
Een advies: werk deze artikelen in de juiste volgorde door en sla niets over. Na afloop heb je uitgebreid kennisgemaakt met Xcode en heb je je eerste app gebouwd!
Het vorige artikel uit deze serie, Stap 4, vind je hier.
Als je een iPhone of iPad hebt, ben je er allang aan gewend: als je het apparaat kantelt, kantelt de app keurig mee. Alle schermonderdelen worden keurig op de juiste plaats neergezet, hoe vaak je het apparaat ook draait.
In de praktijk zijn er een paar stappen nodig om het neerzetten van al die schermonderdelen goed te laten verlopen. Zoals je zojuist hebt gezien, komen subviews (zoals het label met daarop de tekst Mijn eerste app! uit onze DemoApp) niet automatisch op de juiste plaats terecht. Om te zorgen dat dit toch goed gaat, kun je Auto Layout-objecten aan je subviews toevoegen. Door ons tekstlabel van Auto Layout-objecten te voorzien, weet iOS precies wat het moet doen als de subviews moeten worden getoond, of als de schermindeling wijzigt doordat de gebruiker het apparaat kantelt.
In deze stap gaan we dus Auto Layout toepassen. Ook maken we kennis met een nieuwe view: de Image View, waarmee afbeeldingen kunnen worden weergegeven.
Als eerste breiden we onze app uit met een nieuwe view: een Image View, met daarin een afbeelding. Voor deze stap heb je dus een afbeelding nodig. In principe volstaat elke willekeurige afbeelding, maar het mooiste resultaat krijg je met een transparante afbeelding, in PNG-formaat. Als je even geen afbeelding ter beschikking hebt, kun je er eentje downloaden via de volgende URL:
www.iosacademie.nl/startersgids-bestanden/swift.png
Zodra je een plaatje tot je beschikking hebt, kun je aan de slag. Ga terug naar Xcode, stop eventueel de Simulator door op ⌘. te drukken en doe het volgende.
Om onze app overzichtelijk te houden, voegen we het plaatje toe aan de Assets van onze app: een speciale map waarin we onze eigen grafische elementen (afbeeldingen, iconen enzovoort) kunnen bewaren. Klik, in de Navigator, op de map met de naam Assets.xcassets . De inhoud van zowel de Outline als de editor verandert.
Onze Assets-map bevat één (lege) verzameling met de naam AppIcon: zoals de naam al aangeeft, kun je aan deze verzameling afbeeldingen toevoegen voor het icoon dat bij je app hoort.
Een asset (zoals AppIcon) kan meer dan één versie van een afbeelding bevatten, elk met zijn eigen grootte. De ‘1x’-versie is inmiddels verouderd en werd gebruikt op devices met non-retina schermen zoals de iPhone 3 en de eerste iPad-modellen. De ‘2x’-versie wordt inmiddels gebruikt op alle devices behalve de ‘Plus’-modellen van de iPhone: de ‘3x’-versie is speciaal voor die ‘Plus’-modellen bedoeld. Op deze manier kun je afbeeldingen er optimaal laten uitzien op de diverse soorten devices. Denk daaraan bijvoorbeeld aan een versie van 100×100 pixels voor de ‘2x’-categorie en een versie met 150×150 pixels voor de ‘3x’-categorie.
Als je geen zin of tijd hebt om verschillende versies te maken, kun je ook overigens volstaan met één versie: iOS doet dan zijn best om die versie er op alle devices zo goed mogelijk te laten uitzien.
Druk op de Plus-knop (onderaan in de Outline), waarna een menu verschijnt. Kies uit dit menu de eerste optie: New Image Set.
In de volgende afbeelding zie je het resultaat: er is een nieuwe, lege image set aan de app toegevoegd.
Navigeer naar de map waarin je het plaatje hebt staan en sleep het plaatje naar één van de drie vakjes. Vanaf dit moment is dit plaatje beschikbaar in je app.
Op dit moment heet deze collectie Image. We veranderen de naam in Swift: dubbelklik, links bovenaan in de collectie, op het woord Image en vervang dat woord door Swift.
Nu we het plaatje in de Assets van onze app hebben opgenomen, kunnen we het gebruiken. Dat doen we door het in een speciale view te plaatsen: een Image View. Scroll in de Object Library (rechts op het scherm, onderaan in het Utilities-paneel) naar beneden totdat je het Image View-object hebt gevonden.
Klik, in de Navigator, op Main.storyboard, zodat het Storyboard van onze app weer wordt getoond, met daarin de View Controller voor onze app.
Sleep nu, net zoals je in de vorige stap met het tekstlabel hebt gedaan, een Image View vanuit de Object Library naar de hoofd-view. Centreer hem horizontaal (let op de verticale blauwe stippellijn) en zet hem iets boven het tekstlabel (let op de horizontale blauwe stippellijn onderaan in de afbeelding, die de door Apple aangeraden ideale afstand tot dat tekstlabel aangeeft).
Zoals je in de view-hiërarchie (in de Outline, links in de Editor) kunt zien, bevat de hoofd-view van onze app nu twee subviews: het label dat we in de vorige stap hebben toegevoegd en onze zojuist toegevoegde Image View.
(Zie je geen Outline? Kies dan Editor → Show Document Outline).
Klik één keer op de Image View om hem te selecteren. In het Utilities-paneel wordt nu een aantal eigenschappen van de Image View getoond. Degene die we nodig hebben, staat helemaal bovenaan: Image.
Handig om te weten: De eigenschappen die in het Utilities-paneel worden getoond, staan in een bepaalde volgorde: allereerst worden de specifieke eigenschappen voor de geselecteerde view getoond (in dit geval een Image View), daarna de eigenschappen voor de view waar deze view van afstamt (in dit geval een gewone view).
In het Image-veld kun je de afbeelding kiezen die we zojuist aan de Assets van onze app hebben toegevoegd: in dit voorbeeld is dat dus de collectie met de naam Swift. Nadat we dat hebben gedaan, ziet het scherm eruit zoals in de volgende afbeelding; er gaat duidelijk iets mis.
Onze afbeelding wordt gebruikt om de gehele view op te vullen. Dit blijkt uit de eerste optie in het View-gedeelte: Content Mode. Daar staat nu Scale to fill.
Kies hier voor Aspect Fit. Xcode zal onze afbeelding nu, met behoud van de aspect-ratio (de verhouding tussen lengte en breedte) zo schalen dat deze precies in de Image View past.
We kunnen onze app nu testen.
Druk op ⌘R om onze app opnieuw te bouwen en de Simulator te starten. In dit voorbeeld is gekozen voor de iPhone 6s-versie.
Je ziet het: er gaat nog iets mis. De afbeelding staat weliswaar keurig boven het tekstlabel, maar waar op het Storyboard zowel de afbeelding als het tekstlabel keurig zijn gecentreerd, is dat op de gesimuleerde iPhone niet het geval. En als we de Simulator opdracht geven om te kantelen, door op ⌘→ te drukken, ziet de zaak er niet veel beter uit.
Van de gecentreerde views is niet veel meer over. Het lijkt wel alsof ze op een willekeurige plaats zijn neergezet, hoewel de afstand tussen de Image View en het tekstlabel nog wel in orde lijkt. Maar verder lijkt het nergens op. Tijd om kennis te maken met Auto Layout.
Auto Layout is een term voor objecten die je aan een view kunt toevoegen zodat iOS weet hoe je deze view wilt weergeven. Met een Auto Layout-object vertel je iOS bijvoorbeeld dat een view moet worden gecentreerd ten opzichte van de hoofd-view, of dat een view altijd op een bepaalde afstand van een andere view moet worden getoond.
Dit doe je door zogenaamde constraints (in goed Nederlands ‚beperkingen’) aan een view toe te voegen. Zodra een view eenmaal over genoeg Auto Layout-constraints beschikt, weet iOS precies waar je die view op het scherm wilt hebben, ook als de gebruiker van je app zijn of haar iPhone of iPad kantelt.
In ons geval willen we de tekst Mijn eerste app! keurig laten centreren, zowel horizontaal als verticaal. Stop de Simulator: ga terug naar Xcode en druk daar op ⌘. (⌘ punt). Selecteer vervolgens het tekstlabel. Je kunt op het label zelf klikken, maar je kunt ook op de tekst Mijn eerste app! in de view-hiërarchie klikken.
Onderaan in de Editor zie je een speciale werkbalk.
Kijk naar de laatste vier ‘knopjes’ aan de rechterkant. Deze knopjes bieden toegang vier belangrijke Auto Layout-functies: Stack, Align, Add New Constraints en Resolve Auto Layout Issues.
We willen het tekstlabel horizontaal en verticaal centreren. Of liever gezegd: we willen het tekstlabel horizontaal en verticaal gecentreerd uitlijnen. Dat betekent dat we de tweede van de vier opties nodig hebben: Align.
Klik op het tekstlabel om dit te selecteren.
Klik op de Align-knop. waarna een menu verschijnt.
Kruis de onderste twee vakjes aan: Horizontally in Container en Vertically in Container.
Klik op Add 2 Constraints.
Er worden nu twee constraints aan de tekstlabel-view toegevoegd. Dat kun je zien in de View-hiërarchie (in de outline).
Ook zie je de constraints in het Utilities-paneel. Selecteer het tekstlabel en klik op het liniaaltje om de Size Inspector te bekijken, of druk op ⌥⌘5.
Duidelijk is te zien dat er bij deze view twee constraints horen: eentje om hem horizontaal (Center X) te centreren in de superview (de hoofd-view van onze app; de view met de gele achtergrond) en eentje om hem verticaal (Center Y) in de superview te centreren.
Wat het tekstlabel betreft, zijn we nu klaar. Even testen? Druk op ⌘R om de app in de Simulator te starten. En kijk wat er gebeurt: ook in landschapsmodus (druk in de Simulator op ⌘→) staat de tekst nu keurig gecentreerd op zijn plek. Met de afbeelding is nog van alles mis, maar ons tekstlabel doet nu precies wat we willen.
Zoals gezegd: voor het tekstlabel is nu alles in orde. We kunnen nu met onze Image View aan de slag. Hiervoor voegen we maar liefst vier constraints toe: twee om de breedte en hoogte aan te geven, eentje om hem horizontaal binnen de superview (de ‘hoofd’-view; de view met de gele achtergrond) te centreren, en eentje om aan te geven dat hij altijd op de ideale verticale afstand van ons tekstlabel moet worden getoond.
Voor tekstlabels zijn maar twee constraints nodig: ze kunnen hun hoogte en breedte namelijk zelf uitrekenen, op basis van de tekst die erin staat.
We beginnen met de horizontale constraint. Ga terug naar Xcode (stop eventueel de Simulator vanuit Xcode door op ⌘. te drukken) en selecteer onze Image View. Klik opnieuw op de Align-knop en kruis het vakje Horizontally in Container aan. Druk vervolgens op de Add 1 Constraint-knop. Er verschijnen onmiddellijk twee waarschuwingen in de Issue Navigator (links op het scherm: ⌘4); negeer die even. We gaan eerst de verticale constraint toevoegen, evenals de constraints voor breedte en hoogte.
Ons tekstlabel hebben we al verticaal gecentreerd. We willen dat onze Image View boven het tekstlabel wordt getoond, op de door Apple aangeraden ideale afstand. Dat doen we door een constraint toe te voegen die beide views met elkaar verbindt.
Selecteer de Image View door erop te klikken. Klik nu, in de werkbalk onderaan in de Editor, op het Add New Constraints-pictogram.
We willen dat onze Image View op de ideale afstand boven het tekstlabel wordt geplaatst. Dat doen we via het bovenste gedeelte van het Add New Constraints-paneel.
Om onze Image View boven het tekstlabel te laten plaatsen, moeten we een constraint toevoegen aan de onderkant van de Image View. Klik daarom op het symbool onder het vierkantje (het vierkantje geeft onze Image View aan). In de volgende afbeelding wordt dit gedemonstreerd.
Klik nu op het driehoekje in het onderste vakje, waarna een menu openklapt.
Kies de optie Use Standard Value. Hiermee vertellen we Xcode dat we een constraint willen toevoegen aan de onderkant van de Image View, waarmee we de afstand tot het tekstlabel willen aangeven. Tevens vertellen we Xcode dat we de standaardwaarde (dat is de waarde die Apple adviseert als verticale afstand tussen deze twee views) willen gebruiken.
We willen ook nog dat onze image view een vaste breedte en hoogte heeft. Daarvoor kiezen we de hoogtes die Xcode heeft uitgerekend op basis van de image view die we zelf al in de hoofd-view hebben geplaatst: 240 punten breed en 128 punten hoog. Kruis de vakjes Width en Height aan.
Klik nu op Add 3 Constraints. We zijn klaar: de drie constraints zijn toegevoegd, zoals we in het Utilities-paneel kunnen zien.
We hebben nu de noodzakelijke constraints aangebracht: zes in het totaal. Twee constraints om het tekstlabel horizontaal en verticaal te centreren, twee constraints om te zorgen dat de Image View horizontaal wordt gecentreerd en op de ideale afstand boven het tekstlabel wordt getoond, en twee om de vereiste breedte en hoogte van de Image View aan te geven.
We kunnen onze app nu testen. Druk op de toetscombinatie ⌘R en kijk naar het resultaat in de Simulator (kantel het scherm door op ⌘→ te drukken).
Je ziet dat, op een iPhone 6s, de zaak er in portretmodus prima uitziet. De tekst Mijn eerste app! wordt keurig horizontaal en verticaal gecentreerd en de afbeelding wordt er boven gezet.
Als je de Simulator nu opdracht geeft om de iPhone te roteren, zie je dat ook hier alles goed gaat: de tekst wordt opnieuw horizontaal en verticaal gecentreerd en de afbeelding wordt er boven gezet. Precies wat we wilden.
En… dankzij de Auto Layout constraints werkt onze app nu ook prima op bijvoorbeeld een iPhone SE, waarvan het scherm een stuk kleiner is dan dat van de iPhone 6s.
Auto Layout in programmacode: zo werkt het
Voorbeeld-app: zo laat je je iPhone praten
Serie: Een iOS-app maken met Xcode in vijf stappen: Stap 1
Viewcontrollers in een Playground: zo werkt het
Serie: Een iOS-app maken in vijf stappen: Stap 3
Serie: Een iOS-app maken met Xcode in vijf stappen: Stap 2
UIView.animate(): animaties met UIKit