iOS-animaties uitvoeren op weergaven met UIKit en UIView
- over de auteur
- animeren met 60 FPS
- Core Frameworks
- UIKit / UIView animaties
- animatie(withDuration: animations: completion)
- animatewith duration
- UIViewPropertyAnimator
- Wat Is een frame?
- animateKeyframes
- Coreanimatie
- UIView + Core Animation
- UIKitDynamics
- UIKitDynamicAnimator
- UIKitDynamicBehavior
- Performance Tuning
- Core Animation Instrument
- tekening
- Rasterisatie
- het afronden van
over de auteur
Saravanan is een iOS-ingenieur en schrijver bij flexiple and remote tools. Hij heeft gewerkt met meerdere startups in verschillende domeinen.Meer aboutSaravanan↬
- 14 min lezen
- Animatie,iOS,UI,Mobiele
- Opgeslagen voor offline lezen
- Delen op Twitter, LinkedIn
Ik ben al meer dan een decennium ontwikkelaar van iOS en heb zelden artikelen gezien die alle mogelijke manieren om animaties in iOS uit te voeren consolideren. Dit artikel is bedoeld om een primer op iOS animaties met de bedoeling van uitputtend die de verschillende manieren om hetzelfde te doen.
gezien de omvang van het onderwerp, zouden we elk deel bondig op een vrij hoog niveau behandelen. Het doel is om de lezer te onderwijzen met een set van keuzes om animaties toe te voegen aan zijn/ haar iOS-app.
voordat we beginnen met onderwerpen gerelateerd aan iOS, laten we eerst even kijken naar de animatiesnelheid.
animeren met 60 FPS
over het algemeen wordt in video ‘ s elk frame weergegeven door een afbeelding en de framesnelheid bepaalt het aantal gespiegelde afbeeldingen in de reeks. Dit wordt aangeduid als ‘frames per seconde’ of FPS.
FPS bepaalt het aantal stilstaande beelden dat binnen een seconde wordt omgedraaid, wat letterlijk betekent dat hoe meer het aantal afbeeldingen / frames, meer details / informatie worden weergegeven in de video. Dit geldt ook voor animaties.
FPS wordt meestal gebruikt om de kwaliteit van animaties te bepalen. Er is een populaire mening dat een goede animatie moet draaien op 60fps of hoger — iets minder dan 60fps zou voelen een beetje off.
wilt u het verschil zien tussen 30FPS en 60FPS? Moet je dit zien.
merkte u het verschil? Menselijke ogen kunnen zeker de jitter voelen bij lagere fps. Daarom is het altijd een goede gewoonte om ervoor te zorgen dat elke animatie die u maakt, zich houdt aan de basisregel van het draaien op 60FPS of hoger. Dit maakt het gevoel realistischer en levendiger.
nu we naar FPS hebben gekeken, gaan we dieper in op de verschillende core iOS frameworks die ons een manier bieden om animaties uit te voeren.
Core Frameworks
In deze sectie zullen we ingaan op de frameworks in de iOS SDK die gebruikt kunnen worden voor het maken van weergaveanimaties. We zullen een korte wandeling door elk van hen, het uitleggen van hun feature set met een relevant voorbeeld.
UIKit / UIView animaties
UIView is de basisklasse voor elke weergave die inhoud in iOS-apps weergeeft.
UIKit, het framework dat ons UIView geeft, biedt ons al enkele basis animatiefuncties die het voor ontwikkelaars gemakkelijk maken om meer te bereiken door minder te doen.
de API, UIView.animate
, is de makkelijkste manier om weergaven te animeren, omdat de eigenschappen van elke weergave gemakkelijk geanimeerd kunnen worden door de eigenschapswaarden in de op blokken gebaseerde syntaxis op te geven.
in UIKit-animaties wordt aanbevolen om alleen de animeerbare eigenschappen van UIVIew aan te passen, anders zullen er repercussies zijn waarbij de animaties de weergave in een onverwachte toestand kunnen brengen.
animatie(withDuration: animations: completion)
deze methode neemt de animatieduur in, een set van de animeerbare eigenschappen van de weergave die geanimeerd moeten worden. Het completion block geeft een callback wanneer de weergave klaar is met het uitvoeren van de animatie.
bijna elke vorm van animatie zoals verplaatsen, schalen, roteren, vervagen, enz. on a view kan worden bereikt met deze enkele API.
bedenk nu dat u een wijziging in de grootte van een knop wilt animeren of dat u een bepaalde weergave in het scherm wilt inzoomen. Dit is hoe we het kunnen doen met behulp van deUIView.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}
Hier is wat we hier aan het doen zijn:
- we noemen de
UIView.animate
methode met een tijdswaarde die eraan wordt doorgegeven die aangeeft hoe lang de animatie, beschreven in het blok, moet draaien. - we stellen het nieuwe frame van de knop in dat de uiteindelijke status van de animatie moet vertegenwoordigen.
- we stellen de knop
center
in met het centrum van superview, zodat deze in het midden van het scherm blijft.
het bovenstaande blok animatie code moet de animatie van de knop frame veranderen van het huidige frame activeren:
Width = 0, Height = 0
naar het uiteindelijke frame:
Width = Height = newButtonWidth
en zo ziet de animatie eruit:
animatewith duration
deze methode is als een uitbreiding van de animate methode waar u alles kunt doen wat u kunt uitvoeren in de voorgaande API met een aantal fysica gedrag toegevoegd aan de weergave animaties.
bijvoorbeeld, als u de veerdemping effecten wilt bereiken in de animatie die we hierboven hebben gedaan, dan is dit hoe de code eruit zou zien:
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)
Hier is de set van parameters die we gebruiken:
-
duration
geeft de duur van de animatie weer die bepaalt hoe lang het blok code moet draaien. -
delay
vertegenwoordigt de initiële vertraging die we willen hebben voor het begin van de animatie. -
SpringWithDamping
vertegenwoordigt de waarde van het veerkrachtige effect dat we willen dat de weergave zich gedraagt. De waarde moet tussen 0 en 1 liggen. Hoe lager de waarde, hoe hoger de veertrilling. -
velocity
geeft de snelheid weer waarmee de animatie moet starten. -
options
type animatiecurve dat u wilt toepassen op uw weergaveanimatie. - tot slot, het blok code waar we het frame van de knop Instellen die geanimeerd moet worden. Het is hetzelfde als de vorige animatie.
en zo ziet de animatie eruit met de bovenstaande animatieconfiguratie:
UIViewPropertyAnimator
voor een beetje meer controle over animaties is UIViewPropertyAnimator
handig als het ons een manier biedt om te pauzeren en te hervatten animaties. U kunt aangepaste timing hebben en uw animatie interactief en onderbreekbaar te zijn. Dit is erg handig bij het uitvoeren van animaties die ook interactief zijn met acties van gebruikers.
het klassieke gebaar ‘Slide To Unlock’ en de animatie voor afzetting/ uitvouwen van de speler (in de Muziek-app) zijn voorbeelden van interactieve en onderbreekbare animaties. U kunt beginnen met het verplaatsen van een uitzicht met uw vinger, laat het dan los en het uitzicht gaat terug naar de oorspronkelijke positie. Als alternatief kunt u de weergave tijdens de animatie te vangen en verder te slepen met uw vinger.
Hier volgt een eenvoudig voorbeeld van hoe we de animatie kunnen bereiken met UIViewPropertyAnimator
:
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
Hier is wat we doen:
- we noemen de
UIViewProperty
API door de duur en de animatiecurve te passeren. - In tegenstelling tot beide bovenstaande UIView.animate API ‘ s, de animatie zal niet starten, tenzij je het specificeert door jezelf dat wil zeggen Je bent in de volledige controle van de volledige animatie proces/ flow.
stel nu dat je nog meer controle wilt over de animaties. U wilt bijvoorbeeld elk frame in de animatie ontwerpen en beheren. Daar is een andere API voor, animateKeyframes
. Maar voordat we er dieper op ingaan, laten we snel kijken naar wat een frame is, in een animatie.
Wat Is een frame
?
een verzameling van de framewijzigingen/ overgangen van de weergave, van de begintoestand naar de eindtoestand, wordt gedefinieerd als animation
en elke positie van de weergave tijdens de animatie wordt aangeroepen als een frame
.
animateKeyframes
deze API biedt een manier om de animatie zo te ontwerpen dat u meerdere animaties met verschillende timings en overgangen kunt definiëren. Post dit, de API integreert gewoon alle animaties in een naadloze ervaring.
laten we zeggen dat we onze knop op een willekeurige manier op het scherm willen verplaatsen. Laten we eens kijken hoe we de keyframe animation API kunnen gebruiken om dit te doen.
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 }})
Hier is de uitsplitsing:
-
duration
roep de API aan door de duur van de animatie door te geven. -
delay
initiële vertraging duur van de animatie. -
options
het type animatiecurve dat u wilt toepassen op uw beeldanimatie. -
animations
Blok dat alle keyframe-animaties neemt die zijn ontworpen door de ontwikkelaar/ gebruiker. -
addKeyFrame
roep de API aan om elke animatie te ontwerpen. In ons geval hebben we elke beweging van de knop gedefinieerd. We kunnen zoveel animaties als we nodig hebben, toegevoegd aan het blok. -
relativeStartTime
definieert de starttijd van de animatie in de verzameling van het animatieblok. -
relativeDuration
definieert de totale duur van deze specifieke animatie. -
center
in ons geval veranderen we gewoon de middeneigenschap van de knop om de knop rond het scherm te verplaatsen.
en zo ziet de uiteindelijke animatie eruit:
Coreanimatie
elke op UIKit gebaseerde animatie wordt intern vertaald in kernanimaties. Dus, de Core Animation framework fungeert als een backing layer of backbone voor elke UIKit animatie. Vandaar, alle UIKit animatie API ’s zijn niets anders dan ingekapselde lagen van de kern animatie API’ s in een gemakkelijk te consumeren of handige manier.
UIKit animatie API ‘ s bieden niet veel controle over animaties die zijn uitgevoerd over een weergave, omdat ze meestal worden gebruikt voor animeerbare eigenschappen van de weergave. Vandaar dat in dergelijke gevallen, waar u van plan bent om de controle over elk frame van de animatie hebben, is het beter om de onderliggende kern animatie API ‘ s direct te gebruiken. Als alternatief kunnen zowel de UIView-animaties als de core-animaties in combinatie worden gebruikt.
UIView + Core Animation
laten we eens kijken hoe we dezelfde knop veranderen animatie opnieuw kunnen maken samen met het specificeren van de timing curve met behulp van de UIView en Core animatie API ‘ s.
we kunnen CATransaction
’s timingfuncties gebruiken, waarmee u de animatiecurve kunt specificeren en beheren.
laten we eens kijken naar een voorbeeld van een animatie voor het wijzigen van de grootte van een knop met de hoekradius die gebruik maakt van deCATransaction
’s timing functie en een combinatie van UIView animaties:
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
Hier is de uitsplitsing:
-
begin
vertegenwoordigt het begin van het animatiecodeblok. -
duration
Totale animatieduur. -
curve
geeft de timingcurve weer die op de animatie moet worden toegepast. -
UIView.animate
Onze eerste animatie om het frame van de knop te veranderen. -
CABasicAnimation
We maken hetCABasicAnimation
object door hetcornerRadius
van de knop te verwijzen als het toetsenbord aangezien dat is wat we willen animeren. Op dezelfde manier, als je granulair niveau controle wilt hebben over de keyframe animaties, dan kun je deCAKeyframeAnimation
Klasse gebruiken. -
fromValue
vertegenwoordigt de beginwaarde van de animatie, d.w.z. de initiëlecornerRadius
waarde van de knop waar de animatie moet beginnen. -
toValue
vertegenwoordigt de uiteindelijke waarde van de animatie, d.w.z. de uiteindelijkecornerRadius
waarde van de knop waar de animatie moet eindigen. -
cornerRadius
We moeten de eigenschapcornerRadius
van de knop Instellen met de uiteindelijke waarde van de animatie anders wordt de cornerRadius waarde van de knop automatisch teruggezet naar de oorspronkelijke waarde nadat de animatie is voltooid. -
addAnimation
We voegen het animatieobject dat de configuratie van het gehele animatieproces bevat aan de laag toe door het toetsenbord te representeren waarvoor de animatie moet worden uitgevoerd. -
commit
vertegenwoordigt het einde van het animatiecodeblok en start de animatie.
Dit is hoe de uiteindelijke animatie eruit zou zien:
deze blog is een geweldige leesfunctie om meer geavanceerde animaties te maken, aangezien het u netjes door de meeste Core Animation framework Api ‘ s loopt met instructies die u door elke stap van de weg.
UIKitDynamics
UIKit Dynamics is de fysica-engine voor UIKit die u in staat stelt om elk fysisch gedrag zoals botsingen, zwaartekracht, push, snap, etc, toe te voegen aan de UIKit-besturingselementen.
UIKitDynamicAnimator
Dit is de admin klasse van het UIKit Dynamics framework dat alle animaties reguleert die door een bepaalde UI-besturing worden geactiveerd.
UIKitDynamicBehavior
Het stelt u in staat om elk fysisch gedrag toe te voegen aan een animator die het vervolgens in staat stelt om uit te voeren op de weergave die eraan is gekoppeld.
verschillende soorten gedrag voor UIKitDynamics omvatten:
UIAttachmentBehavior
UICollisionBehavior
UIFieldBehavior
UIGravityBehavior
UIPushBehavior
UISnapBehavior
De architectuur van UIKitDynamics ziet er zo uit. Merk op dat de Items 1 tot en met 5 kunnen worden vervangen door een enkele weergave.
laten we wat fysica gedrag toepassen op onze knop. We zullen zien hoe we de zwaartekracht op de knop kunnen toepassen zodat het ons een gevoel geeft om met een echt object om te gaan.
var dynamicAnimator : UIDynamicAnimator!var gravityBehavior : UIGravityBehavior!dynamicAnimator = UIDynamicAnimator(referenceView: self.view) //1gravityBehavior = UIGravityBehavior(items: ) //2dynamicAnimator.addBehavior(gravityBehavior) //3
Hier is de uitsplitsing:
-
UIKitDynamicAnimator
We hebben eenUIKitDynamicAnimator
object gemaakt dat fungeert als orkestrator voor het uitvoeren van animaties. We hebben ook de superview van onze button als referentieweergave doorgegeven. -
UIGravityBehavior
We hebben eenUIGravityBehavior
object aangemaakt en onze knop doorgegeven aan de array-elementen waarop dit gedrag wordt geïnjecteerd. -
addBehavior
We hebben het gravity object aan de animator toegevoegd.
Dit zou een animatie moeten maken zoals hieronder getoond:
we moeten de animator vertellen om de onderkant van het scherm als de grond te beschouwen. Dit is waar
UICollisionBehavior
in beeld komt.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
-
UICollisionBehavior
We hebben eenUICollisionBehavior
object aangemaakt en langs de knop doorgegeven zodat het gedrag aan het element wordt toegevoegd. -
translatesReferenceBoundsIntoBoundary
Het inschakelen van deze eigenschap vertelt de animator om de grens van referentieweergaven als het einde te nemen, wat in ons geval de onderkant van het scherm is. -
addBehavior
hier hebben we botsingsgedrag aan de animator toegevoegd.
nu zou onze knop de grond moeten raken en stil moeten staan zoals hieronder getoond:
dat is vrij netjes, nietwaar?
laten we nu proberen een stuiterend effect toe te voegen zodat ons object realistischer aanvoelt. Om dat te doen, zullen we deUIDynamicItemBehavior
Klasse gebruiken.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
We hebben eenUIDynamicItemBehavior
object aangemaakt en langs de knop doorgegeven zodat het gedrag aan het element wordt toegevoegd. -
elasticity
waarde moet tussen 0-1 liggen, het vertegenwoordigt de elasticiteit, d.w.z. het aantal keren dat het object op en van de grond moet stuiteren wanneer het wordt geraakt. Dit is waar de magie gebeurt – door het aanpassen van deze eigenschap, kunt u onderscheid maken tussen verschillende soorten objecten zoals ballen, flessen, harde voorwerpen en ga zo maar door. -
addBehavior
hier hebben we botsingsgedrag aan de animator toegevoegd.
nu moet onze knop stuiteren als het de grond raakt zoals hieronder getoond:
deze repo is heel nuttig en toont alle UIKitDynamics gedrag in actie. Het biedt ook broncode om te spelen met elk gedrag. Dat, naar mijn mening, moet dienen als een uitgebreide lijst van manieren om iOS-animaties uit te voeren op views!
in de volgende sectie zullen we een korte blik werpen op de tools die ons zullen helpen bij het meten van de prestaties van animaties. Ik zou u ook aanraden om te kijken naar manieren om uw Xcode build te optimaliseren, omdat het een enorme hoeveelheid van uw ontwikkeling tijd zal besparen.
Performance Tuning
In deze sectie zullen we kijken naar manieren om de prestaties van iOS-animaties te meten en af te stemmen. Als iOS-ontwikkelaar hebt u misschien al Xcode-instrumenten gebruikt, zoals geheugenlekken en toewijzingen voor het meten van de prestaties van de algehele app. Ook zijn er instrumenten die kunnen worden gebruikt om de prestaties van animaties te meten.
Core Animation
Instrument
probeer het Core Animation
instrument en u kunt de FPS zien die uw app-scherm levert. Dit is een geweldige manier om de prestaties/ snelheid van een animatie weergegeven in uw iOS-app te meten.
tekening
FPS is sterk verlaagd in de app die zware inhoud zoals afbeeldingen met effecten zoals schaduwen weergeeft. In dergelijke gevallen, in plaats van het toewijzen van de afbeelding direct aan de UIImageView
’s image eigenschap, proberen om de afbeelding afzonderlijk te tekenen in een context met behulp van Core Graphics API’ s. Dit vermindert de weergavetijd van het beeld door de decompressielogica asynchroon uit te voeren wanneer dit gebeurt in een aparte thread in plaats van de hoofdthread.
Rasterisatie
Rasterisatie is een proces dat wordt gebruikt om complexe laaginformatie te cachen, zodat deze weergaven niet opnieuw worden getekend wanneer ze worden gerenderd. Het opnieuw tekenen van weergaven is de belangrijkste oorzaak van de vermindering van FPS en daarom is het het beste om rasterisatie toe te passen op weergaven die meerdere keren worden hergebruikt.
het afronden van
tot slot heb ik ook een lijst van nuttige bronnen voor iOS-animaties samengevat. U vindt dit misschien erg handig bij het werken aan iOS-animaties. Daarnaast kunt u deze set van ontwerptools ook nuttig vinden als een (ontwerp) stap voordat u zich verdiept in animaties.