jeg hører ofte iOS-udviklere stille en variant af det samme nøglespørgsmål:
Hvad er den bedste måde at udvikle en brugergrænseflade på i iOS: gennem Storyboards, NIBs eller kode?
svar på dette spørgsmål, eksplicit eller implicit, har en tendens til at antage, at der er et gensidigt eksklusivt valg, der skal træffes, et, der ofte behandles på forhånd, før udvikling.
jeg er af den opfattelse, at svaret i stedet skal tage form af et eller flere modspørgsmål.
- Hvad er den “bedste” bil?
- tilbage til iOS UI Design
- iOS Storyboards
- dårskaben ved store iOS Storyboards
- Hvornår skal du bruge Storyboards
- når du ikke skal bruge iOS Storyboards
- generelle fordele og ulemper
- Pro: ydeevne
- Pro: prototyper
- Con: genanvendelighed
- Con: datastrøm
- NIBs
- Hvornår skal man bruge NIBs til iOS UI Design
- når du ikke skal bruge nibs
- generelle fordele og ulemper
- Pro: genanvendelighed
- Pro & Con: ydeevne
- iOS Custom Code (Programmatic UIs)
- Pro: under hætten
- Pro: når kode er den eneste mulighed
- Pro: Flet konflikter
- Con: Prototyping
- Con: Refactoring
- Pro: ydeevne
- Pro: Genanvendelighed
- Hvornår skal du bruge kode
- når du ikke skal bruge kode
- et projekt, flere værktøjer
- en simpel brugssag
- indpakning
Hvad er den “bedste” bil?
lad mig forklare med et off-topic eksempel. Sig, at jeg vil købe en bil, og jeg stiller dig et simpelt spørgsmål: “Hvad er det bedste valg?”
kan du virkelig svare ved at foreslå en model eller endda et brand? Ikke sandsynligt, medmindre du foreslår en Ferrari. I stedet vil du sandsynligvis svare med et par andre spørgsmål, som:
- hvad er dit budget?
- hvor mange pladser har du brug for?
- er du interesseret i brændstofforbrug?
- hvordan har du det med sportsbiler?
det er indlysende, at der ikke er noget som en god eller dårlig bil, medmindre den er placeret i en ordentlig sammenhæng—der er bare en god eller dårlig bil baseret på specifikke behov.
tilbage til iOS UI Design
ligesom med vores bil forespørgsel, “Hvad er den bedste måde at udvikle en iOS UI” spørgsmål mangler kontekst. Og overraskende nok, svaret behøver ikke være en catch-all sag.
stort set er der tre typer brugergrænsefladedesignmetoder, som du kan tage, hver med sine fordele og ulemper, dets fans og hadere:
- iOS Storyboards: et visuelt værktøj til at lægge flere applikationsvisninger og overgange mellem dem.
- nib ‘ er: hver NIB-fil svarer til et enkelt visningselement og kan lægges ud i Interface Builder, hvilket også gør det til et visuelt værktøj. Bemærk, at navnet” NIB ” er afledt af filtypen (tidligere .nib og nu .den gamle udtale er vedvaret).
- brugerdefineret kode: dvs.ingen GUI-værktøjer, men snarere håndtering af al brugerdefineret positionering, animation osv. programmatisk.
ingen af disse muligheder er universelt bedre end nogen anden (på trods af hvad du måske hører).
Storyboards er for eksempel den seneste tilføjelse til iOS UI toolkit. Jeg har fået at vide, at de er fremtiden, at de vil erstatte NIBs og brugerdefinerede kode UIs. Jeg ser Storyboards som et nyttigt værktøj, men ikke så meget en erstatning som et supplement til NIBs og brugerdefineret kode. Storyboards er det rigtige valg i nogle, men ikke alle situationer.
yderligere, hvorfor skal du statisk holde dig til en enkelt mulighed, når du kan bruge dem alle (i det samme projekt) og vælge den mekanisme, der bedst passer til det specifikke problem ved hånden?
dette er et spørgsmål, der efter min mening kan generaliseres på et højere niveau, og hvis svar er højt rangeret i min liste over programmeludviklingsprincipper: der er ikke noget universelt sprog, ramme eller teknologi, der er det universelle bedste valg for ethvert programmeludviklingsproblem. Det samme gælder for iOS UI design.
i denne iOS-udviklingsvejledning skal vi udforske hver af disse metoder og introducere brugssager, hvor de bør og ikke bør anvendes, samt måder, hvorpå de kan blandes sammen.
iOS Storyboards
en klassisk begynderfejl er at skabe et massivt projektomfattende iOS Storyboard. Jeg lavede også denne fejl, da jeg først begyndte at arbejde med Storyboards (sandsynligvis fordi det er en fristende rute at tage).
som navnet antyder, er et Storyboard et bord med en historie at fortælle. Det bør ikke bruges til at blande ikke-relaterede historier i et stort volumen. Et storyboard skal indeholde visningskontrollere, der er logisk relateret til hinanden—hvilket ikke betyder enhver visningskontroller.
for eksempel er det fornuftigt at bruge Storyboards ved håndtering:
- et sæt visninger til godkendelse og registrering.
- en flertrins ordreindgangsstrøm.
- en guiden-lignende (dvs.tutorial) strøm.
- et masterdetaljesæt af visninger (f.eks. profillister, profiloplysninger).
i mellemtiden bør Store Storyboards undgås, inklusive Store app-brede Storyboards (medmindre appen er relativt enkel). Før vi går dybere, lad os se hvorfor.
dårskaben ved store iOS Storyboards
Store Storyboards, bortset fra at være vanskelige at gennemse og vedligeholde, tilføjer et lag af kompleksitet til et teammiljø: når flere udviklere arbejder på den samme storyboard-fil på samme tid, er kildekontrolkonflikter uundgåelige. Og mens et storyboard er internt repræsenteret som en tekstfil (faktisk en HML-fil), er sammenlægning normalt ikke triviel.
når udviklere se kildekode, de tilskriver det semantisk betydning. Så når de manuelt fusionerer, er de i stand til at læse og forstå begge sider af en konflikt og handle i overensstemmelse hermed. Et storyboard er i stedet en Storyboard-fil, der administreres af en storyboard, og betydningen af hver kodelinje er ikke altid let at forstå.
lad os tage et meget simpelt eksempel: sig to forskellige udviklere ændrer placeringen af en UILabel
(ved hjælp af autolayout), og sidstnævnte skubber sin forandring og producerer en konflikt som denne (bemærk de modstridende id
attributter):
<layoutGuides> <viewControllerLayoutGuide type="top"/> <viewControllerLayoutGuide type="bottom"/></layoutGuides><layoutGuides> <viewControllerLayoutGuide type="top"/> <viewControllerLayoutGuide type="bottom"/></layoutGuides>
id
selv giver ingen indikation overhovedet om dens sande betydning, så du har intet at arbejde med. Den eneste meningsfulde løsning er at vælge en af konfliktens to sider og kassere den anden. Vil der være bivirkninger? Hvem ved? Ikke dig.
for at lette disse iOS interface design problemer, ved hjælp af flere storyboards i samme projekt er den anbefalede tilgang.
Hvornår skal du bruge Storyboards
Storyboards bruges bedst med flere sammenkoblede visningskontrollere, da deres største forenkling er i overgangen mellem visningskontrollere. Til en vis grad kan de betragtes som en sammensætning af NIBs med visuelle og funktionelle strømme mellem visningskontrollere.
udover at lette navigationsstrømmen er en anden klar fordel, at de eliminerer standardpladekode, der er nødvendig for at poppe, skubbe, præsentere og afvise visningskontrollere. Desuden tildeles visningskontrollere automatisk, så der er ikke behov for manuelt alloc
og init
.
endelig, mens Storyboards bedst bruges til scenarier, der involverer flere visningskontrollere, er det også forsvarligt at bruge et Storyboard, når du arbejder med en enkelt tabelvisningskontroller af tre grunde:
- evnen til at designe bordcelleprototyper på plads hjælper med at holde brikkerne sammen.
- flere celleskabeloner kan designes inde i overordnet tabelvisningscontroller.
- det er muligt at oprette statiske tabelvisninger (en længe ventet tilføjelse, der desværre kun er tilgængelig i Storyboards).
man kunne argumentere for, at flere celleskabeloner også kan designes ved hjælp af NIBs. I sandhed er dette bare et spørgsmål om præference: nogle udviklere foretrækker at have alt på et sted, mens andre er ligeglade.
når du ikke skal bruge iOS Storyboards
et par tilfælde:
- visningen har et kompliceret eller dynamisk layout, bedst implementeret med kode.
- visningen er allerede implementeret med NIBs eller kode.
i disse tilfælde kan vi enten lade visningen være ude af storyboardet eller integrere den i en visningskontroller. Førstnævnte bryder Storyboardets visuelle strøm, men har ingen negative funktionelle eller udviklingsmæssige konsekvenser. Sidstnævnte bevarer denne visuelle strøm, men det kræver yderligere udviklingsindsats, da visningen ikke er integreret i visningskontrolleren: den er bare indlejret som en komponent, hvorfor visningskontrolleren skal interagere med visningen i stedet for at implementere den.
generelle fordele og ulemper
nu hvor vi har en fornemmelse for, hvornår Storyboards er nyttige i iOS UI-design, og inden vi går videre til NIBs i denne tutorial, lad os gennemgå deres generelle fordele og ulemper.
Pro: ydeevne
intuitivt kan du antage, at når et Storyboard er indlæst, instantieres alle dets visningskontrollere straks. Heldigvis er dette kun en abstraktion og ikke sandt for den faktiske implementering: i stedet oprettes kun den oprindelige visningskontroller, hvis nogen. De andre visningskontrollere instantieres dynamisk, enten når en segue udføres eller manuelt fra kode.
Pro: prototyper
Storyboards forenkler prototyping og spottende op af brugergrænseflader og strøm. Faktisk kan en komplet fungerende prototype-applikation med visninger og navigation let implementeres ved hjælp af Storyboards og kun et par kodelinjer.
Con: genanvendelighed
når det kommer til at flytte eller kopiere, er iOS Storyboards dårligt placeret. Et Storyboard skal flyttes sammen med alle dets afhængige visningskontrollere. Med andre ord kan en enkelt visningskontroller ikke ekstraheres individuelt og genbruges andetsteds som en enkelt uafhængig enhed; det er afhængigt af resten af storyboardet for at fungere.
Con: datastrøm
Data skal ofte overføres mellem visningskontrollere, når en app overgår. Storyboardets visuelle strøm er imidlertid brudt i dette tilfælde, da der ikke er spor af, at dette sker i Interface Builder. Storyboards tager sig af håndtering af strømmen mellem visningskontrollere, men ikke strømmen af data. Så destinationscontrolleren skal konfigureres med kode, hvilket tilsidesætter den visuelle oplevelse.
i sådanne tilfælde er vi nødt til at stole på et prepareForSegue:sender
med et if/else-if-skelet som dette:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { NSString *identifier = ; if ("segue_name_1"]) { MyViewController *vc = (MyViewController *) ; ; } else if ("segue_name_2"]) { ... } else if ...}
jeg finder denne tilgang til at være fejl tilbøjelige og unødigt verbose.
NIBs
NIBs er den gamle(er) måde at udføre iOS interface design.
i dette tilfælde betyder “gammel” ikke “dårlig”, “forældet” eller “forældet”. Faktisk er det vigtigt at forstå, at iOS Storyboards ikke er en universel erstatning for NIBs; de forenkler bare UI-implementeringen i nogle tilfælde.
med NIBs kan enhver vilkårlig visning designes, som udvikleren derefter kan vedhæfte til en visningscontroller efter behov.
hvis vi anvender objektorienteret design på vores UIs, er det fornuftigt at opdele en visningskontrollers visning i separate moduler, hver implementeret som en visning med sin egen NIB-fil (eller med flere moduler grupperet i den samme fil). Den klare fordel ved denne tilgang er, at hver komponent er lettere at udvikle, lettere at teste og lettere at debugge.
NIBs deler de fusionskonfliktproblemer, vi så med Storyboards, men i mindre grad, da NIB-filer fungerer i mindre skala.
Hvornår skal man bruge NIBs til iOS UI Design
en delmængde af alle anvendelsessager ville være:
- modale visninger
- enkel login og registrering visninger
- indstillinger
- Popup vinduer
- genanvendelige visningsskabeloner
- genanvendelige tabelcelleskabeloner
i mellemtiden…
når du ikke skal bruge nibs
du bør undgå at bruge nibs til:
- Visninger med dynamisk indhold, hvor layoutet ændres markant afhængigt af indholdet.
- visninger, der af natur ikke let kan designes i Interface Builder.
- se controllere med komplicerede overgange, der kunne forenkles med Storyboarding.
generelle fordele og ulemper
mere generelt, lad os gå gennem fordele og ulemper ved at bruge NIBs.
Pro: genanvendelighed
NIBs er nyttige, når det samme layout deles på tværs af flere klasser.
som en simpel brugssag kunne en visningsskabelon indeholdende et brugernavn og et adgangskodetekstfelt implementeres med de hypotetiske TTLoginView
og TTSignupView
visninger, som begge kunne stamme fra den samme spids. TTLoginView
skulle skjule adgangskodefeltet, og begge skulle angive tilsvarende statiske etiketter (såsom ‘Indtast dit brugernavn’ vs ‘Indtast din adgangskode’), men etiketterne ville have den samme grundlæggende funktionalitet og lignende layout.
Pro & Con: ydeevne
NIBs er dovent indlæst, så de bruger ikke hukommelse, før de skal. Selvom dette kan være en fordel, er der latenstid til den dovne indlæsningsproces, hvilket også gør det til en ulempe.
iOS Custom Code (Programmatic UIs)
ethvert iOS-interface-design, der kan udføres med Storyboards og NIBs, kan også implementeres med rå kode (der var selvfølgelig en tid, hvor udviklere ikke havde luksusen af et så rigt sæt værktøjer).
måske endnu vigtigere, hvad der ikke kan gøres med NIBs og Storyboards kan altid implementeres med kode—forudsat selvfølgelig, at det er teknisk muligt. En anden måde at se på det er, at NIBs og Storyboards implementeres med kode, så deres funktionalitet vil naturligvis være en delmængde. Lad os springe direkte ind i fordele og ulemper.
Pro: under hætten
den største fordel ved at oprette en iOS UI programmatisk: hvis du ved, hvordan du koder en brugergrænseflade, så ved du hvad der sker under hætten, mens det samme ikke nødvendigvis gælder for NIBs og Storyboards.
for at foretage en sammenligning: En lommeregner er et nyttigt værktøj. Men det er ikke en dårlig ting at vide, hvordan man udfører beregninger manuelt.
dette er ikke begrænset til iOS, men til ethvert visual RAD-værktøj (f.eks. Visuelle HTML RAD-miljøer repræsenterer en typisk grænsetilfælde: de bruges til at generere (ofte dårligt skrevet) kode og hævder, at der ikke er behov for HTML-viden, og at alt kan gøres visuelt. Men ingen internetudvikler ville implementere en hjemmeside uden at få sine hænder beskidte: de ved, at manuel håndtering af rå HTML og CSS vil føre til mere modulopbygget, mere effektiv kode.
så mastering af kodningen af iOS-brugergrænseflader giver dig mere kontrol over og større bevidsthed om, hvordan disse stykker passer sammen, hvilket hæver din øvre grænse som udvikler.
Pro: når kode er den eneste mulighed
der er også tilfælde, hvor brugerdefineret iOS-kode er den eneste mulighed for UI-design. Dynamiske layouts, hvor visningselementer flyttes rundt, og forløbet eller layoutet justeres markant baseret på indhold, er typiske eksempler.
Pro: Flet konflikter
mens NIBs og Storyboards led betydeligt af flet konflikter, har kode ikke den samme fejl. Al kode har semantisk betydning, så det er ikke vanskeligere at løse konflikter end normalt.
Con: Prototyping
det er svært at finde ud af, hvordan et layout vil se ud, indtil du har set det i aktion. Desuden kan du ikke visuelt placere visninger og kontroller, så det kan tage meget længere tid at oversætte layoutspecifikationer til en håndgribelig visning sammenlignet med NIBs og Storyboards, der giver dig en øjeblikkelig forhåndsvisning af, hvordan tingene vil gengive.
Con: Refactoring
Refactoring-kode, der blev skrevet for længe siden eller af en anden, bliver også meget mere kompliceret: når elementer placeres og animeres med brugerdefinerede metoder og magiske tal, kan debugging-sessioner blive vanskelige.
Pro: ydeevne
med hensyn til ydeevne er Storyboards og NIBs underlagt overhead af lastning og parsing; og i sidste ende er de indirekte oversat til kode. Det er overflødigt at sige, at dette ikke sker med kodefremstillede UI ‘ er.
Pro: Genanvendelighed
enhver visning implementeret programmatisk kan designes på en genanvendelig måde. Lad os se et par brugssager:
- to eller flere visninger deler en fælles adfærd, men de er lidt forskellige. En basisklasse og to underklasser løser problemet elegant.
- et projekt skal kløves med det formål at oprette en enkelt kodebase, men generere to (eller flere) forskellige applikationer, hver med specifikke tilpasninger.
den samme UI designproces ville være meget mere kompliceret med NIBs og Storyboards. Skabelonfiler tillader ikke Arv, og de mulige løsninger er begrænset til følgende:
- duplikere NIB og Storyboard filer. Derefter har de separate liv og intet forhold til den originale fil.
- Tilsidesæt udseende og adfærd med kode, som kan fungere i enkle tilfælde, men kan føre til betydelig komplikation hos andre. Tunge tilsidesættelser med kode kan også gøre visuelt design ubrugeligt og udvikle sig til en konstant kilde til hovedpine, f. eks., når en bestemt kontrol viser en måde i Interface Builder, men ser helt anderledes ud, når appen kører.
Hvornår skal du bruge kode
det er ofte et godt opkald at bruge Brug brugerdefineret kode til iOS brugergrænseflade design, når du har:
- dynamiske layout.
- Visninger med effekter, såsom afrundede hjørner, skygger osv.
- ethvert tilfælde, hvor brug af NIBs og Storyboards er kompliceret eller umulig.
når du ikke skal bruge kode
generelt kan kodefremstillede UI ‘ er altid bruges. De er sjældent en dårlig ide, så jeg ville sætte en her.
selvom NIBs og Storyboards bringer nogle fordele til bordet, føler jeg, at der ikke er nogen rimelig ulempe, som jeg ville sætte på en liste for at modvirke kodebrug (undtagen måske dovenskab).
et projekt, flere værktøjer
Storyboards, NIBs og kode er tre forskellige værktøjer til opbygning af iOS brugergrænseflade. Vi er heldige at have dem. Fanatikere af programmatiske UI ‘ er tager sandsynligvis ikke de to andre muligheder i betragtning: kode giver dig mulighed for at gøre alt, hvad der er teknisk muligt, mens alternativerne har deres begrænsninger. For resten af udviklerne derude, den hærkniv giver tre værktøjer, som kan bruges alle på en gang, i det samme projekt, effektivt.
hvordan spørger du? Men du kan lide. Her er nogle mulige tilgange:
- Gruppe alle relaterede skærme i separate grupper, og gennemføre hver gruppe med sin egen særskilte Storyboard.
- Design ikke-genanvendelige tabelceller på plads med et Storyboard, inde i tabelvisningskontrolleren.
- Design genanvendelige tabelceller i NIBs for at tilskynde til genbrug og undgå gentagelse, men Indlæs disse NIBs gennem brugerdefineret kode.
- Design brugerdefinerede visninger, kontrolelementer og mellemobjekter ved hjælp af NIBs.
- Brug kode til meget dynamiske visninger og mere generelt til visninger, der ikke let kan implementeres via Storyboards og NIBs, mens boliger viser overgange i et Storyboard.
for at lukke, lad os se på et sidste eksempel, der binder det hele sammen.
en simpel brugssag
sig, at vi vil udvikle en grundlæggende messaging-app med flere forskellige visninger:
- en liste over fulgte venner (med en genanvendelig celleskabelon for at holde brugergrænsefladen konsistent på tværs af fremtidige lister).
- en profildetaljevisning, sammensat i separate sektioner (inklusive profiloplysninger, statistik og en værktøjslinje).
- en liste over meddelelser sendt til og modtaget fra en ven.
- en ny meddelelsesformular.
- en tag-skyvisning, der viser de forskellige tags, der bruges i brugerbeskeder, hvor hvert tag er proportionalt i størrelse med det antal gange, det er blevet brugt.
derudover ønsker vi, at visningerne skal flyde som følger:
- hvis du klikker på et element på listen over fulgte venner, vises den relevante vens profiloplysninger.
- profiloplysningerne viser profilnavn, adresse, statistik, en kort liste over de seneste meddelelser og en værktøjslinje.
for at implementere denne iOS-app vil alle tre af vores UI-værktøjer være nyttige, som vi kan bruge:
- et Storyboard med fire visningskontrollere (listen, Detaljer, Liste over meddelelser og ny meddelelsesformular).
- en separat NIB-fil til den genanvendelige profillistecelleskabelon.
- tre separate NIB-filer til visningen profiloplysninger, en for hver af de separate sektioner, der komponerer den (profiloplysninger, statistik, sidste tre meddelelser) for at give mulighed for bedre vedligeholdelse. Disse NIBs vil blive instantieret som visninger og derefter tilføjet til visningskontrolleren.
- brugerdefineret kode til tag cloud-visningen. Denne visning er et typisk eksempel på en, der ikke kan designes i Interface Builder, hverken gennem StoryBoards eller NIBs. I stedet er det helt implementeret gennem kode. For at opretholde Storyboards visuelle strøm vælger vi at tilføje en tom visningskontroller til storyboardet, implementere tag cloud-visningen som en enkeltstående visning og programmatisk tilføje visningen til visningskontrolleren. Det er klart, at visningen også kunne implementeres inde i visningskontrolleren snarere end som en selvstændig visning, men vi holder dem adskilt for bedre genbrug.
en virkelig grundlæggende mock-up kan se ud:
med det har vi skitseret den grundlæggende konstruktion af en rimelig sofistikeret iOS-app, hvis kernevisninger binder vores tre primære tilgange til UI-design sammen. Husk: der er ingen binær beslutning, der skal træffes, da hvert værktøj har sine styrker og svagheder.
indpakning
som undersøgt i denne turtorial, Storyboards tilføje en mærkbar forenkling til iOS UI design og visuel strøm. De eliminerer også kedelpladekode; men alt dette kommer til en pris, betalt i fleksibilitet. NIBs tilbyder i mellemtiden mere fleksibilitet ved at fokusere på en enkelt visning, men uden visuel strøm. Den mest fleksible løsning er selvfølgelig kode, som har tendens til at være temmelig uvenlig og iboende ikke-visuel.
hvis denne artikel fascinerede dig, anbefaler jeg stærkt at se den store debat fra Ray Venderlich, 55 minutter brugt på en diskussion af NIBs, Storyboards og kodefremstillede UI ‘ er.
til sidst vil jeg understrege en ting: undgå at bruge det forkerte iOS UI-designværktøj for enhver pris. Hvis en visning ikke kan designes med et Storyboard, eller hvis det kan implementeres med NIBs eller kode på en enklere måde, skal du ikke bruge et Storyboard. Tilsvarende, hvis en visning ikke kan designes ved hjælp af NIBs, skal du ikke bruge NIBs. Disse regler, mens enkle, vil gå langt i din uddannelse som udvikler.