Utføre iOS Animasjoner På Visninger Med UIKit og UIView
- Om forfatteren
- Animerer VED 60FPS
- Core Frameworks
- Uikit / UIView Animasjoner
- animasjon (medvarighet: animasjoner: fullføring)
- animateWithDuration
- UIViewPropertyAnimator
- Hva er en frame?
- animateKeyframes
- CoreAnimation
- Uiview + Core Animasjon
- UIKitDynamics
- UIKitDynamicAnimator
- UIKitDynamicBehavior
- Performance Tuning
- Core Animation Instrument
- Tegning
- Rasterisering
- Innpakning
Om forfatteren
Saravanan er en ios ingeniør og forfatter på flexiple og eksterne verktøy. Han har jobbet med flere startups på tvers av ulike domener.Mer omaravanan↬
- 14 min lese
- Animasjon,iOS,UI,Mobil
- Lagret for offline lesing
- Del På Twitter, LinkedIn
div >
denne artikkelen tar sikte på å Være En Primer på iOS animasjoner UTTØMMENDE Dekker ulike måter å gjøre det. Vi starter med å forstå grunnleggende animasjoner, flytte Til Kjernen Rammer bygge et enkelt eksempel ved hjelp av de ulike metodene som tilbys, og til slutt ser på måter å tune ytelse.
jeg har vært en iOS-utvikler i over et tiår nå og har sjelden sett artikler som konsoliderer alle mulige måter å utføre animasjoner i iOS. Denne artikkelen tar sikte på å være en primer på iOS animasjoner med den hensikt å uttømmende dekker de ulike måtene å gjøre det samme.
Gitt omfanget av emnet, vil vi dekke hver del kortfattet på et ganske høyt nivå. Målet er å utdanne leseren med et sett med valg for å legge animasjoner til hans / hennes iOS app.
før vi begynner med emner relatert til iOS, la oss ta en kort titt på animasjonshastigheten.
Animerer VED 60FPS
vanligvis i videoer, er hver ramme representert av et bilde, og bildefrekvensen bestemmer antall bilder vendt i sekvensen. Dette betegnes som ‘rammer per sekund’ eller FPS.
FPS bestemmer antall stillbilder vendt i løpet av et sekund, noe som bokstavelig talt betyr at jo mer antall bilder/ rammer, flere detaljer / informasjon vises i videoen. Dette gjelder også for animasjoner.
FPS brukes vanligvis til å bestemme kvaliteten på animasjonene. Det er en populær oppfatning at enhver god animasjon skal kjøre på 60fps eller høyere – noe mindre enn 60fps ville føle seg litt av.
vil du se forskjellen MELLOM 30FPS OG 60FPS? Sjekk dette!
merket du forskjellen? Menneskelige øyne kan definitivt føle jitter ved lavere fps. Derfor er det alltid en god praksis å sørge for at enhver animasjon du lager, overholder grunnregelen for å kjøre PÅ 60FPS eller høyere. Dette gjør det mer realistisk og levende.Etter å ha sett PÅ FPS, la oss nå dykke inn i de forskjellige kjerne iOS-rammene som gir oss en måte å utføre animasjoner på.
Core Frameworks
i denne delen vil vi berøre rammene i iOS SDK som kan brukes til å lage vis animasjoner. Vi vil gjøre en rask tur gjennom hver av dem, og forklare deres funksjonssett med et relevant eksempel.
Uikit / UIView Animasjoner
UIView Er grunnklassen for alle visninger som viser innhold i iOS-apper.UIKit, rammeverket som gir Oss UIView, gir oss allerede noen grunnleggende animasjonsfunksjoner som gjør det praktisk for utviklere å oppnå mer ved å gjøre mindre.API, UIView.animate
, er den enkleste måten å animere visninger siden noen vis egenskaper kan enkelt animeres ved å gi egenskapsverdiene i blokk – basert syntaks.
I uikit-animasjoner anbefales det å endre bare de animerbare egenskapene Til UIVIew ellers vil det være konsekvenser der animasjonene kan føre til at visningen ender opp i en uventet tilstand.
animasjon (medvarighet: animasjoner: fullføring)
denne metoden tar i animasjonsvarigheten, et sett med visningens animerbare egenskap endres som må animeres. Fullføringsblokken gir en tilbakeringing når visningen er ferdig med å utføre animasjonen.
Nesten alle slags animasjon som flytting, skalering, roterende, falming, etc. på en visning kan oppnås med dette ENKELT API.
vurder nå at du vil animere en knappestørrelsesendring, eller du vil at en bestemt visning skal zoome inn på skjermen. Slik kan vi gjøre det ved hjelp avUIView.animate
API:
let newButtonWidth: CGFloat = 60UIView.animate(withDuration: 2.0) { //1 self.button.frame = CGRect(x: 0, y: 0, width: newButtonWidth, height: newButtonWidth) //2 self.button.center = self.view.center //3}
her er hva vi gjør her:
- vi kaller
UIView.animate
metode med en varighetsverdi overført til den som representerer hvor lenge animasjonen, beskrevet inne i blokken, skal kjøre. - vi setter den nye rammen på knappen som skal representere animasjonens endelige tilstand.
- vi setter knappen
center
med superview-senteret slik at det forblir midt på skjermen.
ovennevnte blokk med animasjonskode skal utløse animasjonen av knappens ramme som endres fra gjeldende ramme:
Width = 0, Height = 0
til siste ramme:
Width = Height = newButtonWidth
og her er hvordan animasjonen vil se ut:
animateWithDuration
denne metoden er som en forlengelse av animate-metoden der du kan gjøre alt du kan utføre i TIDLIGERE API med noen fysikkadferd lagt til visningsanimasjonene.
For eksempel, hvis du vil oppnå fjærdempende effekter i animasjonen som vi har gjort ovenfor, så er dette hvordan koden vil se ut:
let newButtonWidth: CGFloat = 60UIView.animate(withDuration: 1.0, //1 delay: 0.0, //2 usingSpringWithDamping: 0.3, //3 initialSpringVelocity: 1, //4 options: UIView.AnimationOptions.curveEaseInOut, //5 animations: ({ //6 self.button.frame = CGRect(x: 0, y: 0, width: newButtonWidth, height: newButtonWidth) self.button.center = self.view.center}), completion: nil)
her er settet med parametere vi bruker:
-
duration
Representerer varigheten av animasjonen som bestemmer hvor lenge kodeblokken skal kjøre. -
delay
Representerer den første forsinkelsen som vi ønsker å ha før starten av animasjonen. -
SpringWithDamping
Representerer verdien av den fjærende effekten som vi vil at visningen skal oppføre seg. Verdien må være mellom 0 til 1. Jo lavere verdien er, desto høyere er vårens svingning. -
velocity
Representerer hastigheten som animasjonen skal starte med. -
options
type animasjonskurve som du vil bruke på visningsanimasjonen din. - Til Slutt, kodeblokken der vi setter rammen på knappen som må animeres. Det er det samme som forrige animasjon.
og her er hva animasjonen vil se ut med den ovennevnte animasjonskonfigurasjonen:
UIViewPropertyAnimator
for litt mer kontroll over animasjoner, UIViewPropertyAnimator
kommer hendig hvor det gir oss en måte å pause og gjenoppta animasjoner. Du kan ha tilpasset timing og få animasjonen til å være interaktiv og avbrytbar. Dette er veldig nyttig når du utfører animasjoner som også er interaktable med brukerhandlinger.
den klassiske ‘Slide To Unlock’ – bevegelsen og spillervisningen avvis / utvid animasjon (I Musikk-appen) er eksempler på interaktive og avbruddsfrie animasjoner. Du kan begynne å flytte en visning med fingeren, slipp den og visningen går tilbake til sin opprinnelige posisjon. Alternativt kan du fange visningen under animasjonen og fortsette å dra den med fingeren.
Følgende er et enkelt eksempel på hvordan vi kunne oppnå animasjonen ved hjelp avUIViewPropertyAnimator
:
let newButtonWidth: CGFloat = 60let animator = UIViewPropertyAnimator(duration:0.3, curve: .linear) { //1 self.button.frame = CGRect(x: 0, y: 0, width: newButtonWidth, height: newButtonWidth) self.button.center = self.view.center}animator.startAnimation() //2
her er hva vi gjør:
- vi kaller
UIViewProperty
API ved å sende varigheten og animasjonskurven. - I Motsetning til Både UIView ovenfor.animere API-er, animasjonen vil ikke starte med mindre du angir det selv, dvs. du har full kontroll over hele animasjonsprosessen/ flyten.
la Oss nå si at du vil ha enda mer kontroll over animasjonene. Du vil for eksempel utforme og kontrollere hver eneste ramme i animasjonen. Det er en ANNEN API for det, animateKeyframes
. Men før vi dykker inn i det, la oss raskt se på hva en ramme er, i en animasjon.
Hva er en frame
?
en samling av visningens rammeendringer/ overganger, fra starttilstanden til slutttilstanden, er definert som animation
og hver posisjon i visningen under animasjonen kalles som enframe
.
animateKeyframes
DETTE API gir en måte å designe animasjonen på en slik måte at du kan definere flere animasjoner med ulike timings og overganger. Post dette, API bare integrerer alle animasjonene i en sømløs opplevelse.
La oss si at vi ønsker å flytte vår knapp på skjermen på en tilfeldig måte. La oss se hvordan vi kan bruke keyframe animation API for å gjøre det.
UIView.animateKeyframes(withDuration: 5, //1 delay: 0, //2 options: .calculationModeLinear, //3 animations: { //4 UIView.addKeyframe( //5 withRelativeStartTime: 0.25, //6 relativeDuration: 0.25) { //7 self.button.center = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.maxY) //8 } UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.25) { self.button.center = CGPoint(x: self.view.bounds.width, y: start.y) } UIView.addKeyframe(withRelativeStartTime: 0.75, relativeDuration: 0.25) { self.button.center = start }})
her er sammenbrudd:
-
duration
Ring API ved å passere i varigheten av animasjonen. -
delay
Første forsinkelse varighet av animasjonen. -
options
typen animasjonskurve som du vil bruke på visningsanimasjonen din. -
animations
Blokk som tar alle keyframe animasjoner designet av utbygger / bruker. -
addKeyFrame
Ring API for å designe hver animasjon. I vårt tilfelle har vi definert hvert trekk på knappen. Vi kan ha så mange slike animasjoner som vi trenger, lagt til blokken. -
relativeStartTime
Definerer starttidspunktet for animasjonen i samlingen av animasjonsblokken. -
relativeDuration
Definerer den totale varigheten av denne spesifikke animasjonen. -
center
i vårt tilfelle endrer vi bare senteregenskapen til knappen for å flytte knappen rundt skjermen.
Og slik ser de endelige animasjonene ut:
CoreAnimation
Enhver uikit-basert animasjon er internt oversatt til kjerneanimasjoner. Dermed Fungerer Core Animation framework som et backing lag eller ryggrad for Enhver uikit animasjon. Derfor er alle uikit animation Apier ingenting annet enn innkapslede lag av core animation Apier på en lett forbruksvare eller praktisk måte.
uikit animasjon Apier gir ikke mye kontroll over animasjoner som har blitt utført over en visning siden de brukes mest for animerbare egenskaper av visningen. Derfor, i slike tilfeller, hvor du har tenkt å ha kontroll over hver ramme av animasjonen, er det bedre å bruke de underliggende kjerne animasjons Apier direkte. Alternativt kan Både UIView animasjoner og kjerne animasjoner brukes sammen også.
Uiview + Core Animasjon
La oss se hvordan Vi kan gjenskape den samme knappen endre animasjon sammen med å angi timing kurve ved Hjelp Av UIView Og Core Animasjon Apier.
Vi kan bruke CATransaction
‘s timing funksjoner, som lar deg spesifisere og kontrollere animasjonskurven.
La oss se på et eksempel på en knapp størrelse endring animasjon med sin hjørneradius utnytte CATransaction
‘s timing funksjon og en kombinasjon Av uiview animasjoner:
let oldValue = button.frame.width/2let newButtonWidth: CGFloat = 60/* Do Animations */CATransaction.begin() //1CATransaction.setAnimationDuration(2.0) //2CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)) //3// View animations //4UIView.animate(withDuration: 1.0) { self.button.frame = CGRect(x: 0, y: 0, width: newButtonWidth, height: newButtonWidth) self.button.center = self.view.center}// Layer animationslet cornerAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.cornerRadius)) //5cornerAnimation.fromValue = oldValue //6cornerAnimation.toValue = newButtonWidth/2 //7button.layer.cornerRadius = newButtonWidth/2 //8button.layer.add(cornerAnimation, forKey: #keyPath(CALayer.cornerRadius)) //9CATransaction.commit() //10
her er sammenbrudd:
-
begin
Representerer starten på animasjonskodeblokken. -
duration
samlet animasjonsvarighet. -
curve
Representerer tidskurven som må brukes på animasjonen. -
UIView.animate
Vår første animasjon for å endre rammen på knappen. -
CABasicAnimation
vi lagerCABasicAnimation
objektet ved å henvise tilcornerRadius
på knappen som keypath siden det er det vi vil animere. På samme måte, hvis du vil ha granulær nivåkontroll over keyframe-animasjonene, kan du bruke klassenCAKeyframeAnimation
. -
fromValue
Representerer startverdien av animasjonen, dvs. den førstecornerRadius
verdien av knappen fra der animasjonen må starte. -
toValue
Representerer den endelige verdien av animasjonen, dvs. den endeligecornerRadius
verdien av knappen der animasjonen må avsluttes. -
cornerRadius
Vi må settecornerRadius
egenskapen til knappen med den endelige verdien av animasjonen. -
addAnimation
vi legger animasjonsobjektet som inneholder konfigurasjonen av hele animasjonsprosessen til laget ved å representere Tastaturet som animasjonen må utføres for. -
commit
Representerer slutten av animasjonskodeblokken og starter animasjonen.
dette er hvordan den endelige animasjonen vil se ut:
denne bloggen er en flott lese for å bidra til å skape mer avanserte animasjoner som det pent leder deg gjennom De Fleste Av Kjernen Animasjon rammeverk Apier med instruksjoner veilede deg gjennom hvert steg på veien.
UIKitDynamics
UIKit Dynamics er fysikkmotoren For UIKit som lar deg legge til noen fysikk atferd som kollisjon, gravitasjon, push, snap, etc, Til UIKit kontroller.
UIKitDynamicAnimator
dette er administrasjonsklassen Til Uikit Dynamics framework som regulerer alle animasjoner utløst av en GITT UI-kontroll.
UIKitDynamicBehavior
det gjør det mulig å legge til fysikkadferd til en animator som gjør det mulig å utføre på visningen som er knyttet til den.
Ulike typer atferd for Uikitdynamikk inkluderer:
UIPushBehavior
UISnapBehavior
UIAttachmentBehavior
UICollisionBehavior
UIFieldBehavior
UIGravityBehavior
arkitekturen til uikitdynamikk ser noe ut som dette. Merk At Elementene 1 til 5 kan erstattes med en enkelt visning.
La oss bruke litt fysikkadferd på knappen vår. Vi vil se hvordan du bruker tyngdekraften til knappen slik at den gir oss en følelse av å håndtere et ekte objekt.
var dynamicAnimator : UIDynamicAnimator!var gravityBehavior : UIGravityBehavior!dynamicAnimator = UIDynamicAnimator(referenceView: self.view) //1gravityBehavior = UIGravityBehavior(items: ) //2dynamicAnimator.addBehavior(gravityBehavior) //3
her er sammenbruddet:
-
UIKitDynamicAnimator
Vi har laget enUIKitDynamicAnimator
objekt som fungerer som en orkestrator for å utføre animasjoner. Vi har også passert superview av vår knapp som referanse visning. -
UIGravityBehavior
Vi har opprettet etUIGravityBehavior
objekt og send vår knapp inn i arrayelementene som denne oppførselen injiseres på. -
addBehavior
vi har lagt gravitasjonsobjektet til animatoren.
dette bør skape en animasjon som vist nedenfor:
vi bør fortelle animatoren å vurdere bunnen av skjermen for å være bakken. Dette er hvor
UICollisionBehavior
kommer inn i bildet.var dynamicAnimator : UIDynamicAnimator!var gravityBehavior : UIGravityBehavior!var collisionBehavior : UICollisionBehavior!dynamicAnimator = UIDynamicAnimator(referenceView: self.view) //1gravityBehavior = UIGravityBehavior(items: ) //2dynamicAnimator.addBehavior(gravityBehavior) //3collisionBehavior = UICollisionBehavior(items: ) //4collisionBehavior.translatesReferenceBoundsIntoBoundary = true //5dynamicAnimator.addBehavior(collisionBehavior) //6
-
translatesReferenceBoundsIntoBoundary
Aktivering av denne egenskapen forteller animatoren å ta referansevisningsgrensen som slutten, som er bunnen av skjermen i vårt tilfelle. -
addBehavior
vi har lagt kollisjonsadferd til animatoren her.
nå skal knappen vår slå bakken og stå stille som vist nedenfor:
det er ganske pent, ikke sant?Nå, la Oss prøve å legge til en hoppende effekt slik at vårt objekt føles mer ekte. For å gjøre det, vil vi bruke klassen
UIDynamicItemBehavior
.var dynamicAnimator : UIDynamicAnimator!var gravityBehavior : UIGravityBehavior!var collisionBehavior : UICollisionBehavior!var bouncingBehavior : UIDynamicItemBehavior!dynamicAnimator = UIDynamicAnimator(referenceView: self.view) //1gravityBehavior = UIGravityBehavior(items: ) //2dynamicAnimator.addBehavior(gravityBehavior) //3collisionBehavior = UICollisionBehavior(items: ) //4collisionBehavior.translatesReferenceBoundsIntoBoundary = true //5dynamicAnimator.addBehavior(collisionBehavior) //6//Adding the bounce effectbouncingBehavior = UIDynamicItemBehavior(items: ) //7bouncingBehavior.elasticity = 0.75 //8dynamicAnimator.addBehavior(bouncingBehavior) //9
-
UIDynamicItemBehavior
Vi har opprettet enUIDynamicItemBehavior
objekt og passere langs knappen slik at oppførselen er lagt til elementet. -
elasticity
Verdien må være mellom 0-1, den representerer elastisiteten dvs. antall ganger objektet må sprette på og av bakken når det treffes. Det er her magien skjer – ved å tilpasse denne egenskapen kan du skille mellom ulike typer objekter som baller, flasker, harde gjenstander og så videre. -
addBehavior
vi har lagt kollisjonsadferd til animatoren her.
UICollisionBehavior
vi har opprettet en UICollisionBehavior
objekt og gått langs knappen slik at oppførselen er lagt til elementet.
nå skal knappen vår sprette når den treffer bakken som vist nedenfor:
denne repoen er ganske nyttig og viser All Uikitdynamikkadferd i aksjon. Det gir også kildekode for å leke seg med hver oppførsel. Det, etter min mening, bør tjene som en omfattende liste over måter å utføre iOS animasjoner på visninger!
i neste avsnitt vil vi ta en kort titt på verktøyene som vil hjelpe oss med å måle ytelsen til animasjoner. Jeg vil også anbefale deg å se på måter å optimalisere Xcode-bygningen din, siden det vil spare mye av utviklingstiden din.
Performance Tuning
i denne delen vil vi se på måter å måle og justere ytelsen til iOS-animasjoner. Som iOS-utvikler har du kanskje allerede brukt Xcode-Instrumenter som Minnelekkasjer og Tildelinger for å måle ytelsen til den generelle appen. På samme måte er det instrumenter som kan brukes til å måle ytelsen til animasjoner.
Core Animation
Instrument
PrøvCore Animation
instrument, og du bør kunne se FPS som appskjermen din leverer. Dette er en fin måte å måle ytelsen/ hastigheten til enhver animasjon gjengitt i iOS-appen din.
Tegning
FPS er langt senket i appen som viser tungt innhold som bilder med effekter som skygger. I slike tilfeller, i stedet for å tilordne Bildet direkte til UIImageView
‘s bildeegenskap, prøv å tegne bildet separat i en kontekst ved Hjelp Av Core Graphics Apier. Dette reduserer bildevisningstiden for mye ved å utføre bildedekompresjonslogikken asynkront når den gjøres i en egen tråd i stedet for hovedtråden.
Rasterisering
Rasterisering Er en prosess som brukes til å bufre kompleks laginformasjon slik at disse visningene ikke tegnes på nytt når de gjengis. Redrawing av visninger er hovedårsaken til reduksjonen I FPS, og det er derfor best å bruke rasterisering på visninger som skal gjenbrukes flere ganger.
Innpakning
for å konkludere har jeg også oppsummert en liste over nyttige ressurser for iOS-animasjoner. Du kan finne dette veldig nyttig når du arbeider med iOS animasjoner. I tillegg kan du også finne dette settet med designverktøy nyttig som en (design) trinn før hulene i animasjoner.