Articles

efectuarea de animații iOS pe vizualizări cu UIKit și UIView

  • 14 min citit
  • animație,iOS,UI,mobil
  • salvate pentru lectură offline
  • Share on Twitter, LinkedIn

acest articol își propune să fie un primer pe animații iOS exhaustiv care acoperă diferite moduri de a face acest lucru. Începem prin a înțelege elementele de bază ale animațiilor, trecem la cadrele de bază construind un singur exemplu folosind diferitele metode oferite și, în cele din urmă, analizăm modalități de a regla performanța.

sunt dezvoltator iOS de peste un deceniu și rareori am văzut articole care consolidează toate modalitățile posibile de a efectua animații în iOS. Acest articol își propune să fie un primer pe animații iOS cu intenția de a acoperi exhaustiv diferitele moduri de a face același lucru.

având în vedere extensivitatea subiectului, am acoperi fiecare parte succint la un nivel destul de ridicat. Scopul este de a educa cititorul cu un set de opțiuni pentru a adăuga animații în aplicația sa iOS.

înainte de a începe cu subiecte legate de iOS, să aruncăm o scurtă privire la viteza de animație.

animarea la 60 FPS

În general, în videoclipuri, fiecare cadru este reprezentat de o imagine, iar rata cadrelor determină numărul de imagini oglindite în secvență. Acest lucru este numit ca ‘cadre pe secundă’ sau FPS.

FPS determină numărul de imagini statice oglindită într-o secundă, ceea ce înseamnă literalmente că mai mult numărul de imagini/ cadre, mai multe detalii / informații sunt afișate în video. Acest lucru este valabil și pentru animații.

FPS este de obicei folosit pentru a determina calitatea animațiilor. Există o opinie populară că orice animație bună ar trebui să ruleze la 60fps sau mai mare — orice mai puțin de 60fps s-ar simți puțin.

vrei să vezi diferența dintre 30FPS și 60fps? Fii atent!

ai observat diferența? Ochii umani pot simți cu siguranță bruiajul la fps mai mic. Prin urmare, este întotdeauna o bună practică pentru a vă asigura că orice animație creați, aderă la regula de bază de funcționare la 60FPS sau mai mare. Acest lucru îl face să se simtă mai realist și mai viu.

după ce ne-am uitat la FPS, Să aprofundăm acum diferitele cadre iOS de bază care ne oferă o modalitate de a efectua animații.

cadre de bază

În această secțiune, vom atinge cadrele din SDK-ul iOS care pot fi utilizate pentru crearea animațiilor de vizualizare. Vom face o plimbare rapidă prin fiecare dintre ele, explicând setul lor de caracteristici cu un exemplu relevant.

UIkit / UIView Animations

UIView este clasa de bază pentru orice vizualizare care afișează conținut în aplicațiile iOS.

UIKit, cadrul care ne oferă UIView, ne oferă deja câteva funcții de animație de bază care fac convenabil pentru dezvoltatori să realizeze mai mult făcând mai puțin.

API-ul,UIView.animate, este cel mai simplu mod de a anima vizualizări, deoarece proprietățile oricărei vizualizări pot fi ușor animate prin furnizarea valorilor proprietății în sintaxa bazată pe blocuri.

în animațiile UIKit, se recomandă modificarea numai a proprietăților animabile ale UIVIew altfel vor exista repercusiuni în care animațiile ar putea determina vizualizarea să ajungă într-o stare neașteptată.

animation(withDuration: animations: completion)

această metodă preia durata animației, un set de modificări ale proprietății animabile ale Vizualizării care trebuie animate. Blocul de finalizare oferă un apel invers atunci când vizualizarea se face cu efectuarea animației.

aproape orice fel de animație, cum ar fi mișcarea, scalarea, rotirea, decolorarea etc. pe o vedere poate fi realizată cu acest singur API.

acum, considerați că doriți să animați o modificare a dimensiunii butonului sau doriți ca o anumită vizualizare să mărească ecranul. Acesta este modul în care o putem face folosindUIView.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}

Iată ce facem aici:

  1. numimUIView.animate metoda cu o valoare de durată transmisă care reprezintă Cât timp ar trebui să ruleze animația descrisă în interiorul blocului.
  2. am setat noul cadru al butonului care ar trebui să reprezinte starea finală a animației.
  3. setăm butonulcenter cu Centrul supervizorului său, astfel încât să rămână în centrul ecranului.

blocul de cod de animație de mai sus ar trebui să declanșeze animația cadrului butonului care se schimbă de la cadrul curent:

Width = 0, Height = 0

la cadrul final:

Width = Height = newButtonWidth

și iată cum ar arăta animația:

animateWithDuration

această metodă este ca o extensie a metodei animate unde puteți face tot ce puteți efectua în API-ul anterior cu unele comportamente fizice adăugate la animațiile de vizualizare.

de exemplu, dacă doriți să obțineți efecte de amortizare a arcului în animația pe care am făcut-o mai sus, atunci acesta este modul în care ar arăta codul:

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)

Iată setul de parametri pe care îl folosim:

  1. duration
    reprezintă durata animației care determină cât timp ar trebui să ruleze blocul de cod.
  2. delay
    reprezintă întârzierea inițială pe care dorim să o avem înainte de începerea animației.
  3. SpringWithDamping
    reprezintă valoarea efectului elastic pe care dorim ca vederea să se comporte. Valoarea trebuie să fie între 0 și 1. Cu cât valoarea este mai mică, cu atât este mai mare oscilația arcului.
  4. velocity
    reprezintă viteza cu care animația ar trebui să înceapă.
  5. options
    tipul curbei de animație pe care doriți să o aplicați animației dvs. de vizualizare.
  6. în cele din urmă, blocul de cod în care setăm cadrul butonului care trebuie animat. Este la fel ca animația anterioară.

și iată cum ar arăta animația cu configurația de animație de mai sus:

UIViewPropertyAnimator

pentru un pic mai mult control asupra animații, UIViewPropertyAnimator vine la îndemână în cazul în care ne oferă o modalitate de a întrerupe și relua animații. Puteți avea sincronizare personalizată și animația dvs. să fie interactivă și întreruptibilă. Acest lucru este foarte util atunci când efectuați animații care pot fi interacționate și cu acțiunile utilizatorului.

gestul clasic ‘Slide to Unlock’ și vizualizarea playerului respingerea / extinderea animației (în aplicația Muzică) sunt exemple de animații interactive și întreruptibile. Puteți începe să mutați o vizualizare cu degetul, apoi eliberați-o și vizualizarea va reveni la poziția inițială. Alternativ, puteți prinde vizualizarea în timpul animației și continuați să o trageți cu degetul.

urmează un exemplu simplu despre cum am putea realiza animația folosind 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

Iată ce facem:

  1. numimUIViewProperty API prin trecerea duratei și a curbei de animație.
  2. spre deosebire de ambele UIView de mai sus.animați API – urile, animația nu va începe decât dacă o specificați de unul singur, adică sunteți în controlul deplin al procesului/ fluxului complet de animație.

acum, să spunem că doriți și mai mult control asupra animațiilor. De exemplu, doriți să proiectați și să controlați fiecare cadru din animație. Există un alt API pentru asta, animateKeyframes. Dar, înainte de a intra în ea, să ne uităm rapid la ceea ce este un cadru, într-o animație.

ce este unframe?

o colecție de modificări/tranziții ale cadrului vizualizării, de la starea de pornire la starea finală, este definită caanimation și fiecare poziție a vizualizării în timpul animației este denumităframe.

animateKeyframes

acest API oferă o modalitate de a proiecta animația în așa fel încât să puteți defini mai multe animații cu diferite temporizări și tranziții. Postați acest lucru, API-ul integrează pur și simplu toate animațiile într-o singură experiență perfectă.

să spunem că vrem să ne mișcăm butonul pe ecran într-un mod aleatoriu. Să vedem cum putem folosi API-ul de animație keyframe pentru a face acest lucru.

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 }})

Iată defalcarea:

  1. duration
    apelați API trecând în durata animației.
  2. delay
    durata inițială de întârziere a animației.
  3. options
    tipul curbei de animație pe care doriți să o aplicați animației dvs. de vizualizare.
  4. animations
    bloc care ia toate animațiile keyframe proiectate de dezvoltator / utilizator.
  5. addKeyFrame
    apelați API-ul pentru a proiecta fiecare animație. În cazul nostru, am definit fiecare mișcare a butonului. Putem avea atâtea animații de care avem nevoie, adăugate la bloc.
  6. relativeStartTime
    definește ora de începere a animației în colecția blocului de animație.
  7. relativeDuration
    definește durata totală a acestei animații specifice.
  8. center
    În cazul nostru, schimbăm pur și simplu proprietatea centrală a butonului pentru a muta butonul în jurul ecranului.

și așa arată animațiile finale:

CoreAnimation

orice animație bazată pe UIKit este tradusă intern în animații de bază. Astfel, cadrul de animație de bază acționează ca un strat de suport sau coloană vertebrală pentru orice animație UIKit. Prin urmare, toate API-urile de animație UIKit nu sunt altceva decât straturi încapsulate ale API-urilor de animație de bază într-un mod ușor consumabil sau convenabil.

API-urile de animație UIKit nu oferă prea mult control asupra animațiilor care au fost efectuate pe o vizualizare, deoarece sunt utilizate mai ales pentru proprietățile animabile ale Vizualizării. Prin urmare, în astfel de cazuri, în cazul în care intenționați să aveți control asupra fiecărui cadru al animației, este mai bine să utilizați direct API-urile de animație de bază. Alternativ, atât animațiile UIView, cât și animațiile de bază pot fi utilizate și împreună.

UIView + Core Animation

Să vedem cum putem recrea aceeași animație de schimbare a butonului împreună cu specificarea curbei de sincronizare folosind API-urile UIView și Core Animation.

putem folosiCATransactionfuncții de sincronizare, care vă permite să specificați și să controlați curba de animație.

să ne uităm la un exemplu de animație de schimbare a dimensiunii butonului cu raza sa de colț folosind CATransaction funcția de sincronizare și o combinație de animații UIView:

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

Iată defalcarea:

  1. begin
    reprezintă începutul blocului de cod de animație.
  2. duration
    durata totală de animație.
  3. curve
    reprezintă curba de sincronizare care trebuie aplicată animației.
  4. UIView.animate
    prima noastră animație pentru a schimba cadrul butonului.
  5. CABasicAnimation
    creăm obiectulCABasicAnimation referindu-ne lacornerRadius al butonului ca tastatură, deoarece asta vrem să animăm. În mod similar, dacă doriți să aveți control la nivel granular asupra animațiilor cadru cheie, atunci puteți utiliza CAKeyframeAnimation clasă.
  6. fromValue
    reprezintă valoarea inițială a animației, adică valoarea inițialăcornerRadius a butonului de unde trebuie să înceapă animația.
  7. toValue
    reprezintă valoarea finală a animației, adică valoarea finalăcornerRadius a butonului unde trebuie să se termine animația.
  8. cornerRadius
    trebuie să setămcornerRadius proprietatea butonului cu valoarea finală a animației, altfel valoarea cornerradius a butonului va reveni automat la valoarea inițială după finalizarea animației.
  9. addAnimation
    atașăm obiectul de animație care conține configurația întregului proces de animație la strat, reprezentând tastatura pentru care trebuie efectuată animația.
  10. commit
    reprezintă sfârșitul blocului de cod de animație și începe animația.

așa ar arăta animația finală:

acest blog este o citire excelentă pentru a ajuta la crearea de animații mai avansate, deoarece vă plimbă perfect prin majoritatea API-urilor cadru de animație de bază cu instrucțiuni care vă ghidează fiecare pas din drum.

UIKitDynamics

UIkit Dynamics este motorul de fizica pentru UIKit care vă permite să adăugați orice comportamente fizica, cum ar fi coliziune, gravitație, push, snap, etc, la controalele UIKit.

UIKitDynamicAnimator

aceasta este clasa admin a UIkit Dynamics framework care reglementează toate animațiile declanșate de orice control UI dat.

UIKitDynamicBehavior

Acesta vă permite să adăugați orice comportament fizica la un animator care apoi îi permite să efectueze pe punctul de vedere atașat la acesta.

diferite tipuri de comportamente pentru UIKitDynamics includ:

  • UIAttachmentBehavior
  • UICollisionBehavior
  • UIFieldBehavior

  • UIGravityBehavior
  • UIPushBehavior
  • UISnapBehavior

arhitectura uikitdynamics arată cam așa. Rețineți că elementele de la 1 la 5 pot fi înlocuite cu o singură vizualizare.

să aplicăm un comportament fizic butonului nostru. Vom vedea cum să aplicăm gravitația butonului, astfel încât să ne ofere un sentiment de a face cu un obiect real.

var dynamicAnimator : UIDynamicAnimator!var gravityBehavior : UIGravityBehavior!dynamicAnimator = UIDynamicAnimator(referenceView: self.view) //1gravityBehavior = UIGravityBehavior(items: ) //2dynamicAnimator.addBehavior(gravityBehavior) //3

Iată defalcarea:

  1. UIKitDynamicAnimator
    am creat unUIKitDynamicAnimator obiect care acționează ca un orchestrator pentru realizarea animațiilor. Am trecut, de asemenea, supravegherea butonului nostru ca vizualizare de referință.
  2. UIGravityBehavior
    am creat unUIGravityBehavior obiect și treceți butonul nostru în elementele matrice pe care este injectat acest comportament.
  3. addBehavior
    am adăugat obiectul gravitațional la animator.
    acest lucru ar trebui să creeze o animație așa cum se arată mai jos:
    observați cum butonul cade din centru (poziția sa inițială) a ecranului în partea de jos și dincolo.

    ar trebui să spunem animatorului să considere partea de jos a ecranului ca fiind solul. Aici intră în imagineUICollisionBehavior.

    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
  4. UICollisionBehavior
    am creat unUICollisionBehavior obiect și a trecut de-a lungul butonului, astfel încât comportamentul este adăugat la elementul.
  5. translatesReferenceBoundsIntoBoundary
    activarea acestei proprietăți îi spune animatorului să ia limita vizualizărilor de referință ca sfârșit, care este partea de jos a ecranului în cazul nostru.
  6. addBehavior
    am adăugat comportamentul de coliziune la animator aici.
    acum, Butonul nostru ar trebui să atingă solul și să stea nemișcat așa cum se arată mai jos:

    asta e destul de îngrijit, nu-i așa?
    acum, să încercăm să adăugăm un efect de săritură, astfel încât obiectul nostru să se simtă mai real. Pentru a face acest lucru, vom folosi UIDynamicItemBehavior clasa.

    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
  7. UIDynamicItemBehavior
    am creat un obiectUIDynamicItemBehavior și treceți de-a lungul butonului astfel încât comportamentul să fie adăugat elementului.
  8. elasticity
    valoarea trebuie să fie între 0-1, reprezintă elasticitatea adică numărul de ori obiectul trebuie să sări pe și de pe sol atunci când este lovit. Acest lucru este în cazul în care magia se întâmplă — prin tweaking această proprietate, puteți face diferența între diferite tipuri de obiecte, cum ar fi bile, sticle, hard-obiecte și așa mai departe.
  9. addBehavior
    am adăugat comportamentul de coliziune la animator aici.

acum, Butonul nostru ar trebui să sară când atinge solul așa cum se arată mai jos:

acest repo este destul de util și arată toate comportamentele UIKitDynamics în acțiune. Acesta oferă, de asemenea, codul sursă pentru a juca în jurul cu fiecare comportament. Asta, în opinia mea, ar trebui să servească drept o listă extinsă de modalități de a efectua animații iOS pe vizualizări!

în secțiunea următoare, vom arunca o scurtă privire asupra instrumentelor care ne vor ajuta în măsurarea performanței animațiilor. De asemenea, v-aș recomanda să analizați modalități de optimizare a construirii Xcode, deoarece va economisi o cantitate imensă de timp de dezvoltare.

Performance Tuning

În această secțiune, vom analiza modalități de măsurare și reglare a performanței animațiilor iOS. Ca dezvoltator iOS, este posibil să fi folosit deja instrumente Xcode, cum ar fi scurgeri de memorie și alocări pentru măsurarea performanței aplicației generale. În mod similar, există instrumente care pot fi utilizate pentru a măsura performanța animațiilor.

Core Animation Instrument

încercați instrumentulCore Animation și ar trebui să puteți vedea FPS-ul pe care îl oferă ecranul aplicației. Aceasta este o modalitate excelentă de a măsura performanța/ viteza oricărei animații redate în aplicația dvs. iOS.

desen

FPS este redus foarte mult în aplicația care afișează conținut grele, cum ar fi imagini cu efecte, cum ar fi umbre. În astfel de cazuri, în loc să atribuiți imaginea direct proprietății imaginii UIImageView, încercați să desenați imaginea separat într-un context folosind API-uri grafice de bază. Acest lucru reduce excesiv timpul de afișare a imaginii prin efectuarea logică de decompresie a imaginii asincron atunci când se face într-un fir separat în loc de firul principal.

rasterizare

rasterizare este un proces folosit pentru a cache informații strat complex, astfel încât aceste puncte de vedere nu sunt redesenate ori de câte ori acestea sunt randate. Redesenarea vizualizărilor este cauza majoră a reducerii FPS și, prin urmare, este mai bine să aplicați rasterizarea pe vizualizările care vor fi refolosite de mai multe ori.

Wrapping Up

pentru a încheia, am rezumat, de asemenea, o listă de resurse utile pentru animații iOS. Puteți găsi acest lucru foarte util atunci când lucrați la animații iOS. În plus, puteți găsi, de asemenea, acest set de instrumente de proiectare utile ca un pas (de proiectare) înainte de a intra în animații.