Hogyan segített a CAAnimation legyőzni az animációk létrehozásától való félelmemet

Ez a cikk a CA animációk iOS használatára összpontosít, hogy sima animációkat készítsen.

Az első iOS-munkával töltött napjaim alatt nagyon ideges lettem, amikor egy tervező odajött hozzám, és animációt kért az alkalmazásból, amin dolgoztak.

Korábban azt gondoltam, hogy könnyű kidolgozni az animációkat - de ennek megvalósítása viszont nagyon nehéz feladat volt.

A megvalósításhoz segítséget kérnék a Google-tól, a StackOverflow-tól és társaimtól.

A folyamat során kifejlesztettem az animációk fóbiáját, és mindig megpróbáltam elkerülni őket. De mindez egy napon megváltozott.

A CAAnimation megtalálása

Egy alkalommal animálnom kellett egy képsorozatot egy nézetben. Szóval mi volt az első lépésem? Nyilvánvaló, hogy a StackOverflow!

Az első link megkapta a kódot.

let image_1 = UIImage(named: "image-1")! let image_2 = UIImage(named: "image-2")! let image_3 = UIImage(named: "image-3")! let images = [image_1, image_2, image_3] let animatedImage = UIImage.animatedImage(with: images, duration: 2.0) imageView.image = animatedImage

Elég egyértelműnek tűnik, igaz? Ha ilyen egyszerű lenne, nem írnám ezt a cikket.

Erre az animációra volt szükség:

És mint valószínűleg világossá vált, közel sem voltam hozzá. Be voltam szorulva. Hogyan kellett volna elvégeznem ennyi testreszabást abban az animációban és szinkronizálni mindet?

Aztán kollégám azt mondta, hogy próbáljam ki a CAAnimation programot. Olvastam róla és kipróbáltam egy mintaprojektben. Csodálkozásomra valóban hatalmas és könnyen használható volt.

Mi az alapanimáció?

A Core Animation segít több animáció végrehajtásában, szinte nulla CPU használat mellett.

Magas képkockasebességet és sok testreszabást biztosít, amelyeket nagyon kis kóddal használhat.

További részletek a dokumentumokban találhatók itt: //developer.apple.com/documentation/quartzcore

Néhány óra alatt meg tudtam valósítani az alapvető megvalósítást:

func addAnimation(firstImageView: UIImageView, secondImageView: UIImageView) { let basicAnimation1 = getBasicAnimation(withInitialPostion: centerPosition, finalPos: finalPosition) firstImageView.layer.add(basicAnimation1, forKey: "position") let basicAnimation2 = self.getBasicAnimation(withInitialPostion: self.initalPosition, finalPos: self.centerPosition) secondImageView.layer.add(basicAnimation2, forKey: "position") self.addNextImage(forImageView: firstImageView) } func getBasicAnimation(withInitialPostion initialPos: CGPoint, finalPos: CGPoint) -> CABasicAnimation { let basicAnimation = CABasicAnimation(keyPath: "position") basicAnimation.fromValue = NSValue(cgPoint: initialPos) basicAnimation.toValue = NSValue(cgPoint: finalPos) basicAnimation.duration = 1 basicAnimation.isRemovedOnCompletion = false basicAnimation.fillMode = CAMediaTimingFillMode.forwards basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) return basicAnimation }

Ehhez a megvalósításhoz a CABasicAnimation programot használtam .

A CABasicAnimation osztály segít animálni egy réteg tulajdonságot (ami lehet háttérszín, fedettség, helyzet, méretarány) két érték között. Csak meg kell adnia a kezdő és a végértéket, a többiről gondoskodni kell. Az animáció azonnal megkezdődik a következő futási ciklusban, az itt részletesebben leírtak szerint.

Most térjünk vissza a problémánkra.

Ennek megvalósításához két képnézetet készítettem, és két külön képet adtam hozzájuk. Aztán folyamatosan animáltam őket egymás után a CAAnimation segítségével.

A forráskódot itt találja.

Ha megvizsgálja az utolsó gif-et, látni fogja, hogy valami nincs rendben. Mielőtt az ajándékdoboz első képe eltűnik, a fejhallgató rövid ideig villog, majd a kép felfelé mozog.

Miért történik ez?

Ez azért van, mert amint hozzáadjuk az animációt a képnézethez, hozzáadjuk a következő képet ehhez a nézethez (5. és 6. sor):

private func addAnimation(firstImageView: UIImageView, secondImageView: UIImageView) { let basicAnimation1 = getBasicAnimation(withInitialPostion: centerPosition, finalPos: finalPosition) firstImageView.layer.add(basicAnimation1, forKey: "position") let basicAnimation2 = self.getBasicAnimation(withInitialPostion: self.initalPosition, finalPos: self.centerPosition) secondImageView.layer.add(basicAnimation2, forKey: "position") self.addNextImage(forImageView: firstImageView) }

Itt az animáció mindkét képének szinkronizálásának problémájával küzdünk. De mindig van megoldás a CAAnimation alkalmazással.

CA tranzakciók

A CA tranzakciók segítenek több animáció szinkronizálásában. Biztosítja, hogy az összes animáció, amelyet összegyűjtöttünk, egyszerre induljon el.

Ezenkívül adhat egy befejezési blokkot az animációinak, amelyet akkor hajtanak végre, amikor az összes animáció egy csomagban elkészül.

Bővebben itt olvashat.

private func addAnimation(firstImageView: UIImageView, secondImageView: UIImageView) { CATransaction.begin() CATransaction.setCompletionBlock { self.addNextImage(forImageView: firstImageView) } let basicAnimation1 = getBasicAnimation(withInitialPostion: centerPosition, finalPos: finalPosition) firstImageView.layer.add(basicAnimation1, forKey: "position") CATransaction.commit() let basicAnimation2 = self.getBasicAnimation(withInitialPostion: self.initalPosition, finalPos: self.centerPosition) secondImageView.layer.add(basicAnimation2, forKey: "position") }

Azzal kezded, hogy írsz CATransaction.begin(). Ezután írjon szinkronizálva minden animációt, amelyet meg szeretne csinálni. Végül hívja meg, CATransaction.commit()amely elindítja az animációt a blokkban.

Lássuk, hogyan néz ki animációnk most:

Utolsó dolog, amit meg kellett tennem, az volt, hogy hozzáadtam a Spring effektust az animációhoz. Szerencsére a CAAnimationnek is volt erre megoldása.

CA tavaszi animáció

A CA Spring Animation egy réteghez hozzáadva rugószerű hatást kölcsönöz neki, úgy tűnik, hogy egy rugó a cél felé húzza.

Minél tovább van a réteg a céltól, annál nagyobb a felgyorsulás felé.

Ez lehetővé teszi a fizikai alapú tulajdonságok, például a rugó csillapításának és merevségének ellenőrzését. - Dokumentumok

További információt az Apple dokumentációjában olvashat: //developer.apple.com/documentation/quartzcore/caspringanimation

Vezessük be a meglévő kódunkra:

private func getSpringAnimation(withInitialPostion initialPos: CGPoint, finalPos: CGPoint) -> CASpringAnimation { let basicAnimation = CASpringAnimation(keyPath: "position") basicAnimation.fromValue = NSValue(cgPoint: initialPos) basicAnimation.toValue = NSValue(cgPoint: finalPos) basicAnimation.duration = basicAnimation.settlingDuration basicAnimation.damping = 14 basicAnimation.initialVelocity = 5 basicAnimation.isRemovedOnCompletion = false basicAnimation.fillMode = CAMediaTimingFillMode.forwards return basicAnimation }

A munkám itt zajlik.

Összefoglalva, íme néhány előny a CA animációk használatának:

  • Könnyen használhatók és megvalósíthatók
  • Nagyon sok testreszabás érhető el
  • Lehetőség van több animáció szinkronizálására
  • Almost zero CPU usage

These the just a few of the advantages. The possibilities are endless.

Now, whenever requirements come for animation, I feel confident designing and implementing them. And I hope you also feel the same way after reading this.

Feel free to leave any suggestions or feedback.