iOS animációk végrehajtása UIKit és UIView nézeteken
- a szerzőről
- animálás 60 kép/mp sebességgel
- Core Frameworks
- UIKit/ UIView animációk
- animáció(withDuration: animations: completion)
- animateWithDuration
- UIViewPropertyAnimator
- mi az a frame?
- animateKeyframes
- CoreAnimation
- UIView + Core Animation
- UIKitDynamics
- UIKitDynamicAnimator
- UIKitDynamicBehavior
- teljesítményhangolás
- Core Animation eszköz
- rajz
- Raszterezés
- becsomagolás
a szerzőről
Saravanan egy iOS mérnök és író flexiple és távoli eszközök. Több Startuppal dolgozott együtt különböző területeken.Továbbiakcaravanan GmbH
- 14 perc olvasás
- animáció,iOS,UI,mobil
- offline olvasásra mentve
- Megosztás a Twitteren, LinkedIn-en
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:
- hívjuk a
UIView.animate
metódust olyan időtartamértékkel, amely azt mutatja, hogy a blokkban leírt animációnak mennyi ideig kell futnia. - beállítjuk a gomb Új keretét, amely az animáció végső állapotát képviseli.
- a
center
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:
-
duration
Az animáció időtartamát jelenti, amely meghatározza, hogy a kódblokknak mennyi ideig kell futnia. -
delay
a kezdeti késleltetést jelenti, amelyet az animáció kezdete előtt szeretnénk elérni. -
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. -
velocity
Az animáció indulási sebességét jelöli. -
options
a nézet animációjára alkalmazni kívánt animációs görbe típusa. - 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:
- a
UIViewProperty
API-t az időtartam és az animációs görbe átadásával hívjuk meg. - 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 animation
definiá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:
-
duration
hívja az API átadásával időtartama az animáció. -
delay
Az animáció kezdeti késleltetési időtartama. -
options
a nézet animációjára alkalmazni kívánt animációs görbe típusa. -
animations
blokk, amely a fejlesztő/ felhasználó által tervezett összes kulcskép animációt veszi igénybe. -
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. -
relativeStartTime
meghatározza az animáció kezdési idejét az animációs blokk gyűjteményében. -
relativeDuration
meghatározza az adott animáció teljes időtartamát. -
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 aCATransaction
idő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 CATransaction
idő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:
-
begin
Az animációs kódblokk kezdetét jelenti. -
duration
Az animáció teljes időtartama. -
curve
az animációra alkalmazandó időzítési görbét jelöli. -
UIView.animate
az első animáció változtatni a keret a gombot. -
CABasicAnimation
aCABasicAnimation
objektumot úgy hozzuk létre, hogy a gombcornerRadius
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 aCAKeyframeAnimation
osztályt. -
fromValue
Az animáció kezdőértékét jelenti, azaz a kezdeticornerRadius
annak a gombnak az értékét, ahonnan az animációnak indulnia kell. -
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. -
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. -
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. -
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
-
UIPushBehavior
-
UISnapBehavior
UIGravityBehavior
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:
-
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. -
UIGravityBehavior
létrehoztunk egyUIGravityBehavior
objektumot, és átadjuk a gombunkat a tömb elemeinek, amelyeken ez a viselkedés be van fecskendezve. -
addBehavior
hozzáadtuk a gravitációs objektumot az animátorhoz.
ennek létre kell hoznia egy animációt az alábbiak szerint:meg kell mondanunk az animátornak, hogy vegye figyelembe a képernyő alját a talajnak. Itt jön képbe a
UICollisionBehavior
.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
létrehoztunk egyUICollisionBehavior
objektumot, amelyet a gomb mentén továbbítottunk, hogy a viselkedés hozzáadódjon az elemhez. -
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. -
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 aUIDynamicItemBehavior
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
-
UIDynamicItemBehavior
létrehoztunk egyUIDynamicItemBehavior
objektumot, és adja át a gombot úgy, hogy a viselkedés hozzáadódik az elemhez. -
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. -
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 UIImageView
ké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.