Articles

iOS animációk végrehajtása UIKit és UIView nézeteken

  • 14 perc olvasás
  • animáció,iOS,UI,mobil
  • offline olvasásra mentve
  • Megosztás a Twitteren, LinkedIn-en

ez a cikk célja, hogy az iOS animációk alapozója legyen, kimerítően lefedve ennek különböző módjait. Kezdjük azzal, hogy megértjük az animációk alapjait, áttérünk az alapvető keretrendszerekre, egyetlen példát építve a kínált különböző módszerekkel, végül pedig megvizsgáljuk a teljesítmény hangolásának módjait.

több mint egy évtizede vagyok iOS fejlesztő, és ritkán láttam olyan cikkeket, amelyek konszolidálják az animációk végrehajtásának minden lehetséges módját az iOS rendszerben. Ez a cikk célja, hogy alapozó legyen az iOS animációkon azzal a szándékkal, hogy kimerítően lefedje a különböző módszereket.

tekintettel a téma kiterjedtségére, az egyes részeket tömören, meglehetősen magas szinten fedjük le. A cél az, hogy oktassák az olvasó egy sor választási hozzáadni animációk ő/ ő iOS app.

mielőtt elkezdenénk az iOS-hez kapcsolódó témákkal, vessünk egy rövid pillantást az animáció sebességére.

animálás 60 kép/mp sebességgel

a videókban általában minden képkockát egy kép képvisel, és a képsebesség határozza meg a sorozatban tükrözött képek számát. Ezt nevezik ‘képkocka másodpercenként’ vagy FPS.

az FPS meghatározza a másodpercen belül megfordított állóképek számát, ami szó szerint azt jelenti, hogy minél több kép/ képkocka van, annál több részlet/ információ jelenik meg a videóban. Ez igaz az animációkra is.a

FPS-t általában az animációk minőségének meghatározására használják. Van egy népszerű vélemény, hogy minden jó animációnak 60 kép / mp vagy annál nagyobb sebességgel kell futnia-bármi, ami kevesebb, mint 60 kép / mp, kissé kikapcsoltnak érzi magát.

szeretné látni a különbséget a 30 kép / mp és a 60 kép / mp között? Ezt figyeld!

észrevetted a különbséget? Az emberi szem határozottan érezheti a rázkódást alacsonyabb fps-nél. Ezért mindig jó gyakorlat annak biztosítása, hogy az Ön által létrehozott animáció megfeleljen a 60 kép / mp vagy annál magasabb sebességű futás alapszabályának. Ez teszi valósághűbbé és élhetőbbé.

miután megnéztük az FPS-t, most mélyüljünk el a különböző alapvető iOS-keretrendszerekben, amelyek módot nyújtanak az animációk végrehajtására.

Core Frameworks

ebben a részben az iOS SDK keretrendszereit fogjuk érinteni, amelyek megtekintési animációk létrehozására használhatók. Egy gyors sétát fogunk tenni mindegyiken, elmagyarázva a funkciókészletüket egy releváns példával.

UIKit/ UIView animációk

az UIView minden olyan nézet alaposztálya, amely tartalmat jelenít meg az iOS alkalmazásokban.

az UIKit, az UIView-t biztosító keretrendszer már biztosít néhány alapvető animációs funkciót, amelyek megkönnyítik a fejlesztők számára, hogy többet érjenek el kevesebbel.

az API, UIView.animate, a legegyszerűbb módja a nézetek animálásának, mivel bármely nézet tulajdonságai könnyen animálhatók azáltal, hogy megadják a tulajdonságértékeket a blokk alapú szintaxisban.

az UIKit animációkban ajánlott csak az uiview animálható tulajdonságait módosítani, különben következményei lesznek, ha az animációk miatt a nézet váratlan állapotba kerülhet.

animáció(withDuration: animations: completion)

Ez a módszer az animáció időtartamát veszi figyelembe, a nézet animálható tulajdonságváltozásainak halmazát, amelyeket animálni kell. A befejezési blokk visszahívást ad, amikor a nézet az animáció végrehajtásával történik.

szinte bármilyen animáció, például mozgás, méretezés, forgatás, fakulás stb. egy nézet lehet elérni ezzel az egyetlen API.

most fontolja meg, hogy animálni szeretne egy gombméret-változtatást, vagy egy adott nézetet szeretne nagyítani a képernyőre. Így tudjuk megtenni a UIView.animate API használatával:

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}

itt van, amit itt csinálunk:

  1. hívjuk aUIView.animate metódust olyan időtartamértékkel, amely azt mutatja, hogy a blokkban leírt animációnak mennyi ideig kell futnia.
  2. beállítjuk a gomb Új keretét, amely az animáció végső állapotát képviseli.
  3. acenter gombot úgy állítottuk be, hogy a superview központja a képernyő közepén maradjon.

a fenti animációs kódblokknak aktiválnia kell a gomb képkockájának animációját az aktuális képkockáról:

Width = 0, Height = 0

a végső képkockára:

Width = Height = newButtonWidth

így nézne ki az animáció:

animateWithDuration

Ez a módszer olyan, mint egy kiterjesztése az animate módszer, ahol meg lehet csinálni mindent, amit el tud végezni a korábbi API néhány fizika viselkedés hozzá a nézet animációk.

például, ha rugócsillapító hatásokat szeretne elérni a fenti animációban, akkor a kód így nézne ki:

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)

itt van az általunk használt paraméterek halmaza:

  1. duration
    Az animáció időtartamát jelenti, amely meghatározza, hogy a kódblokknak mennyi ideig kell futnia.
  2. delay
    a kezdeti késleltetést jelenti, amelyet az animáció kezdete előtt szeretnénk elérni.
  3. SpringWithDamping
    annak a ruganyos hatásnak az értékét jelöli, amelyet a nézetnek viselkednie kell. Az értéknek 0 és 1 között kell lennie. Minél alacsonyabb az érték, annál nagyobb a rugó rezgése.
  4. velocity
    Az animáció indulási sebességét jelöli.
  5. options
    a nézet animációjára alkalmazni kívánt animációs görbe típusa.
  6. végül a kódblokk, ahol beállítjuk az animálni kívánt gomb keretét. Ugyanaz, mint az előző animáció.

így nézne ki az animáció a fenti animációs konfigurációval:

UIViewPropertyAnimator

az animációk egy kicsit nagyobb ellenőrzéséhez UIViewPropertyAnimator jól jön, ahol ez lehetővé teszi számunkra, hogy szüneteltessük és folytassuk az animációkat. Lehet egyéni időzítés, és az animáció, hogy interaktív és megszakítható. Ez nagyon hasznos olyan animációk végrehajtásakor, amelyek kölcsönhatásba léphetnek a felhasználói műveletekkel is.

a klasszikus ‘Slide to Unlock’ gesztus és a lejátszó nézet elvetése/ kibontása animáció (A Zene alkalmazásban) példák az interaktív és megszakítható animációkra. Elindíthat egy nézetet az ujjával, majd elengedheti, és a nézet visszatér eredeti helyzetébe. Alternatív megoldásként elkaphatja a nézetet az animáció során, és folytathatja az ujjával történő húzást.

Az alábbiakban egy egyszerű példa arra, hogyan tudnánk elérni az animációt a 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

itt van, amit csinálunk:

  1. aUIViewProperty API-t az időtartam és az animációs görbe átadásával hívjuk meg.
  2. ellentétben mind a fenti UIView.animate API, Az animáció nem indul el, ha nem adja meg egyedül, azaz te vagy a teljes irányítást a teljes animációs folyamat / áramlás.

most tegyük fel, hogy még jobban szeretné ellenőrizni az animációkat. Például meg szeretné tervezni és irányítani az animáció minden egyes képkockáját. Van egy másik API erre, animateKeyframes. De mielőtt belemerülnénk, gyorsan nézzük meg, mi a keret, egy animációban.

mi az a frame?

a nézet keretváltozásainak/ átmeneteinek gyűjteménye A kezdő állapottól a végső állapotig animationdefiniálva van, és az animáció során a nézet minden pozícióját frame néven hívják meg.

animateKeyframes

Ez az API lehetővé teszi az animáció tervezését oly módon, hogy több animációt definiálhat különböző időzítéssel és átmenettel. Tegye ezt, az API egyszerűen integrálja az összes animációt egyetlen zökkenőmentes élménybe.

tegyük fel, hogy véletlenszerűen szeretnénk mozgatni a gombot a képernyőn. Lássuk, hogyan tudjuk használni a keyframe animáció API erre.

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

itt a bontás:

  1. duration
    hívja az API átadásával időtartama az animáció.
  2. delay
    Az animáció kezdeti késleltetési időtartama.
  3. options
    a nézet animációjára alkalmazni kívánt animációs görbe típusa.
  4. animations
    blokk, amely a fejlesztő/ felhasználó által tervezett összes kulcskép animációt veszi igénybe.
  5. addKeyFrame
    hívja meg az API-t minden animáció megtervezéséhez. Esetünkben meghatároztuk a gomb minden mozdulatát. Annyi ilyen animációt kaphatunk, amennyire szükségünk van, hozzáadva a blokkhoz.
  6. relativeStartTime
    meghatározza az animáció kezdési idejét az animációs blokk gyűjteményében.
  7. relativeDuration
    meghatározza az adott animáció teljes időtartamát.
  8. center
    esetünkben egyszerűen megváltoztatjuk a gomb középső tulajdonságát a gomb mozgatásához a képernyőn.

és így néz ki a végső animáció:

CoreAnimation

minden UIKit alapú animáció belsőleg lefordítva core animációk. Így a Core Animation framework bármilyen UIKit animáció hátlapjaként vagy gerinceként működik. Ezért az összes UIKit animációs API nem más, mint a mag animációs API-k kapszulázott rétegei, könnyen fogyasztható vagy kényelmes módon.

az UIKit animációs API-k nem sok ellenőrzést biztosítanak a nézet felett végrehajtott animációk felett, mivel ezeket leginkább a nézet animálható tulajdonságaihoz használják. Ezért ilyen esetekben, amikor az animáció minden képkockáját ellenőrizni kívánja, jobb, ha közvetlenül az alapul szolgáló alapvető animációs API-kat használja. Alternatív megoldásként mind az UIView animációk, mind a core animációk együtt is használhatók.

UIView + Core Animation

nézzük meg, hogyan tudjuk újra létrehozni ugyanazt a gombváltoztató animációt, az időzítési görbe megadásával együtt az UIView és a Core Animation API-k segítségével.

használhatjuk aCATransactionidőzítési funkcióit, amelyek lehetővé teszik az animációs görbe megadását és vezérlését.

nézzünk meg egy példát egy gombméret – változtatási animációra, amelynek saroksugara a CATransactionidőzítési funkcióját és az UIView animációk kombinációját használja:

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

itt van a bontás:

  1. begin
    Az animációs kódblokk kezdetét jelenti.
  2. duration
    Az animáció teljes időtartama.
  3. curve
    az animációra alkalmazandó időzítési görbét jelöli.
  4. UIView.animate
    az első animáció változtatni a keret a gombot.
  5. CABasicAnimation
    a CABasicAnimation objektumot úgy hozzuk létre, hogy a gomb cornerRadius gombjára hivatkozunk billentyűzetként, mivel ezt szeretnénk animálni. Hasonlóképpen, ha szemcsés szintű vezérlést szeretne a kulcskép animációk felett, akkor használhatja a CAKeyframeAnimation osztályt.
  6. fromValue
    Az animáció kezdőértékét jelenti, azaz a kezdeti cornerRadius annak a gombnak az értékét, ahonnan az animációnak indulnia kell.
  7. toValue
    Az animáció végső értékét jelenti, azaz a végső cornerRadius annak a gombnak az értékét, ahol az animációnak véget kell érnie.
  8. cornerRadius
    be kell állítanunk a gombcornerRadius tulajdonságát az animáció végső értékével, különben a gomb cornerRadius értéke automatikusan visszaáll a kezdeti értékre az animáció befejezése után.
  9. addAnimation
    Az animációs objektumot, amely a teljes animációs folyamat konfigurációját tartalmazza, a réteghez csatoljuk azzal a billentyűzettel, amelyhez az animációt végre kell hajtani.
  10. commit
    Az animációs kódblokk végét jelöli, és elindítja az animációt.

így nézne ki a végső animáció:

Ez a blog egy nagyszerű olvasmány, amely segít a fejlettebb animációk létrehozásában, mivel szépen végigvezeti Önt az alapvető animációs keret API-k többségén, utasításokkal, amelyek az út minden lépésén keresztül.

UIKitDynamics

az UIKit Dynamics az UIKit fizikai motorja, amely lehetővé teszi bármilyen fizikai viselkedés, például ütközés, gravitáció, push, snap stb.hozzáadását az UIKit vezérlőkhöz.

UIKitDynamicAnimator

Ez az UIKit Dynamics framework admin osztálya, amely szabályozza az adott felhasználói felület vezérlése által kiváltott összes animációt.

UIKitDynamicBehavior

Ez lehetővé teszi, hogy adjunk minden fizikai viselkedés egy animátor, amely lehetővé teszi, hogy végre a nézet csatolt hozzá.

az UIKitDynamics különféle viselkedései a következők:

  • UIAttachmentBehavior
  • UICollisionBehavior
  • UIFieldBehavior
  • UIGravityBehavior

  • UIPushBehavior
  • UISnapBehavior

az uikitdynamics architektúrája valahogy így néz ki. Vegye figyelembe, hogy az 1-5. tételeket egyetlen nézet helyettesítheti.

alkalmazzunk néhány fizikai viselkedést a gombunkra. Látni fogjuk, hogyan kell alkalmazni a gravitációt a gombra, hogy ez egy valódi tárgy kezelésének érzését adja nekünk.

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

itt van a bontás:

  1. UIKitDynamicAnimator
    létrehoztunk egyUIKitDynamicAnimator objektumot, amely animációk végrehajtására szolgál. Azt is átment a superview a gomb, mint a referencia nézet.
  2. UIGravityBehavior
    létrehoztunk egy UIGravityBehavior objektumot, és átadjuk a gombunkat a tömb elemeinek, amelyeken ez a viselkedés be van fecskendezve.
  3. addBehavior
    hozzáadtuk a gravitációs objektumot az animátorhoz.
    ennek létre kell hoznia egy animációt az alábbiak szerint:

    figyelje meg, hogyan esik le a gomb a képernyő közepétől (eredeti helyzetétől) az aljára és azon túl.

    meg kell mondanunk az animátornak, hogy vegye figyelembe a képernyő alját a talajnak. Itt jön képbe aUICollisionBehavior.

    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
    létrehoztunk egy UICollisionBehavior objektumot, amelyet a gomb mentén továbbítottunk, hogy a viselkedés hozzáadódjon az elemhez.
  5. translatesReferenceBoundsIntoBoundary
    ennek a tulajdonságnak az engedélyezése azt mondja az animátornak, hogy a referencia nézetek határát vegye végének, amely esetünkben a képernyő alja.
  6. addBehavior
    itt hozzáadtuk az animátor ütközési viselkedését.
    most, a gomb a földre, és állni, mint az alábbi ábrán látható:

    ez elég ügyes, nem?
    most próbáljuk meg hozzáadni egy pattogó hatást, hogy tárgyunk valóságosabbnak érezze magát. Ehhez a UIDynamicItemBehavior osztályt fogjuk használni.

    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
    létrehoztunk egy UIDynamicItemBehavior objektumot, és adja át a gombot úgy, hogy a viselkedés hozzáadódik az elemhez.
  8. elasticity
    az értéknek 0-1 között kell lennie, ez a rugalmasságot jelenti, azaz azt, hogy hányszor kell az objektumnak ugrálnia a földön, amikor eltalálja. Itt történik a varázslat — ennek a tulajdonságnak a módosításával meg lehet különböztetni a különféle tárgyakat, például golyókat, palackokat, kemény tárgyakat stb.
  9. addBehavior
    itt hozzáadtuk az animátor ütközési viselkedését.

most a gombunknak ugrálnia kell, amikor földet ér, az alábbiak szerint:

Ez a repo nagyon hasznos, és megmutatja az összes UIKitDynamics viselkedést működés közben. Azt is előírja, forráskód játszani körül minden viselkedés. Véleményem szerint ennek az iOS animációk nézeteken történő végrehajtásának széles körű listájaként kell szolgálnia!

a következő részben röviden áttekintjük azokat az eszközöket, amelyek segítenek nekünk az animációk teljesítményének mérésében. Azt is javasolnám, hogy vizsgálja meg az Xcode felépítésének optimalizálásának módjait, mivel ez hatalmas mennyiségű fejlesztési időt takarít meg.

teljesítményhangolás

ebben a részben megvizsgáljuk az iOS animációk teljesítményének mérésére és hangolására szolgáló módszereket. IOS-fejlesztőként előfordulhat, hogy már használta az Xcode eszközöket, például a Memóriaszivárgásokat és az allokációkat a teljes alkalmazás teljesítményének mérésére. Hasonlóképpen vannak olyan eszközök, amelyek felhasználhatók az animációk teljesítményének mérésére.

Core Animation eszköz

próbálja ki aCore Animation eszközt, és látnia kell az alkalmazás képernyőjén megjelenő FPS-t. Ez egy nagyszerű módszer az iOS alkalmazásban megjelenített animáció teljesítményének/ sebességének mérésére.

rajz

FPS jelentősen csökkentette az alkalmazás, amely megjeleníti a nehéz Tartalom, mint a képek hatások, mint az árnyékok. Ilyen esetekben ahelyett, hogy a képet közvetlenül a UIImageViewkép tulajdonságához rendelné, próbálja meg a képet külön-külön rajzolni egy kontextusban a Core Graphics API-k segítségével. Ez túlságosan csökkenti a kép megjelenítési idejét azáltal, hogy aszinkron módon hajtja végre a kép dekompressziós logikáját, ha a fő szál helyett külön szálban történik.

Raszterezés

a Raszterezés olyan folyamat, amelyet összetett réteginformációk gyorsítótárazására használnak, hogy ezek a nézetek ne legyenek újrarajzolva, amikor megjelenítik őket. A nézetek újrarajzolása a fő oka az FPS csökkenésének, ezért a legjobb, ha raszterizálást alkalmaznak olyan nézetekre, amelyeket többször újra felhasználnak.

becsomagolás

befejezésül összefoglaltam az iOS animációk hasznos forrásainak listáját is. Lehet, hogy ez nagyon hasznos, ha dolgozik iOS animációk. Ezenkívül ez a tervezési eszközkészlet is hasznos lehet (tervezési) lépésként, mielőtt az animációkba merülne.