Πώς η CAAnimation με βοήθησε να κατακτήσω τον φόβο μου για τη δημιουργία κινούμενων σχεδίων

Αυτό το άρθρο επικεντρώνεται στη χρήση CA Animations στο iOS για την ομαλή κινούμενη εικόνα.

Κατά τη διάρκεια των αρχικών μου ημερών με το iOS, θα ήμουν πολύ νευρικός κάθε φορά που ένας σχεδιαστής ήρθε σε μένα και μου ζήτησε κάποια κινούμενα σχέδια στην εφαρμογή στην οποία εργάζονταν.

Συνήθιζα να πιστεύω ότι ήταν εύκολο να επινοήσω το σχέδιο για κινούμενα σχέδια - αλλά από την άλλη πλευρά, η εφαρμογή του ήταν πολύ δύσκολο.

Θα λάβω βοήθεια από την Google, το StackOverflow και τους συναδέλφους μου για την εφαρμογή.

Κατά τη διάρκεια της διαδικασίας ανέπτυξα μια φοβία κινουμένων σχεδίων και πάντα προσπαθούσα να τα αποφύγω. Αλλά όλα άλλαξαν μια μέρα.

Εύρεση CAAnimation

Μια φορά, έπρεπε να ζωγραφίσω μια ακολουθία εικόνων σε μια προβολή. Ποιο ήταν λοιπόν το πρώτο μου βήμα; Προφανώς, StackOverflow!

Ο πρώτος σύνδεσμος πήρε τον κωδικό.

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

Φαίνεται αρκετά απλό, σωστά; Αν ήταν τόσο απλό, δεν θα γράφω αυτό το άρθρο.

Αυτό ήταν το κινούμενο σχέδιο που απαιτήθηκε:

Και όπως έχει καταστεί πιθανώς σαφές, δεν ήμουν πουθενά κοντά του. Είχα κολλήσει. Πώς έπρεπε να κάνω τόσες πολλές προσαρμογές σε αυτό το κινούμενο σχέδιο και να συγχρονίσω όλες αυτές;

Τότε ο συνάδελφός μου μου είπε να δοκιμάσω το CAAnimation. Διάβασα για αυτό και το δοκίμασα σε ένα δείγμα έργου. Με εκπλήσσει, ήταν πραγματικά ισχυρό και εύκολο στη χρήση.

Τι είναι το Core Animation;

Το Core Animation σάς βοηθά να εκτελείτε πολλές κινούμενες εικόνες με σχεδόν μηδενική χρήση CPU.

Σας δίνει υψηλό ρυθμό καρέ και πολλές προσαρμογές που μπορείτε να χρησιμοποιήσετε με πολύ λίγο κώδικα.

Μπορείτε να βρείτε περισσότερες λεπτομέρειες στα έγγραφα εδώ: //developer.apple.com/documentation/quartzcore

Ήμουν σε θέση να κάνω μια βασική εφαρμογή σε μερικές ώρες:

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 }

Για αυτήν την εφαρμογή, χρησιμοποίησα το CABasicAnimation .

Η κλάση CABasicAnimation σάς βοηθά να κινήσετε μια ιδιότητα επιπέδου (η οποία μπορεί να είναι χρώμα φόντου, αδιαφάνεια, θέση, κλίμακα) μεταξύ δύο τιμών. Απλά πρέπει να δώσετε μια τιμή έναρξης και λήξης και τα υπόλοιπα θα φροντιστούν. Το κινούμενο σχέδιο ξεκινά αμέσως στον επόμενο βρόχο εκτέλεσης όπως περιγράφεται πληρέστερα εδώ.

Τώρα, πίσω στο πρόβλημά μας.

Για να το εφαρμόσω, πήρα δύο προβολές εικόνων και τις πρόσθεσα δύο ξεχωριστές εικόνες. Τότε συνέχισα να τα ζωγραφίζω το ένα μετά το άλλο χρησιμοποιώντας το CAAnimation.

Μπορείτε να βρείτε τον πηγαίο κώδικα εδώ.

Εάν εξετάσετε το τελευταίο gif, θα δείτε ότι κάτι δεν πάει καλά. Πριν από την προβολή της πρώτης εικόνας ενός κουτιού δώρου, τα ακουστικά αναβοσβήνουν για λίγο και στη συνέχεια η εικόνα κινείται προς τα πάνω.

Γιατί συμβαίνει αυτό?

Επειδή μόλις προσθέσουμε το κινούμενο σχέδιο στην προβολή εικόνας, προσθέτουμε την επόμενη εικόνα σε αυτήν την προβολή (γραμμές αριθ. 5 και 6):

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

Εδώ αγωνιζόμαστε με το ζήτημα του τρόπου συγχρονισμού και των δύο εικόνων στο κινούμενο σχέδιο. Αλλά υπάρχει πάντα μια λύση με το CAAnimation.

Συναλλαγές CA

Οι συναλλαγές CA μας βοηθούν να συγχρονίσουμε πολλές κινούμενες εικόνες μαζί. Διασφαλίζει ότι όλα τα κινούμενα σχέδια που έχουμε συγκεντρώσει όλα ξεκινούν ταυτόχρονα.

Επίσης, μπορείτε να δώσετε ένα μπλοκ ολοκλήρωσης στα κινούμενα σχέδια σας, το οποίο θα εκτελεστεί όταν ολοκληρωθούν όλες οι κινούμενες εικόνες σας σε ένα πακέτο.

Μπορείτε να διαβάσετε περισσότερα γι 'αυτό εδώ.

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

Ξεκινάτε γράφοντας CATransaction.begin(). Στη συνέχεια, γράψτε όλα τα κινούμενα σχέδια που θέλετε να κάνετε συγχρονισμό. Τέλος, καλέστε την CATransaction.commit()οποία θα ξεκινήσει το κινούμενο σχέδιο στο μπλοκ.

Ας δούμε πώς φαίνεται η κινούμενη εικόνα μας τώρα:

Ένα τελευταίο πράγμα που έπρεπε να κάνω ήταν να προσθέσω το εφέ Spring στο animation. Ευτυχώς, το CAAnimation είχε και μια λύση για αυτό.

CA Spring Animation

Το CA Spring Animation, όταν προστίθεται σε ένα στρώμα, δίνει ένα εφέ ελατηρίου σε αυτό, έτσι ώστε να φαίνεται να τραβιέται προς έναν στόχο από ένα ελατήριο.

Όσο περισσότερο το επίπεδο είναι από το στόχο, τόσο μεγαλύτερη είναι η επιτάχυνση προς αυτό.

Επιτρέπει τον έλεγχο των φυσικών χαρακτηριστικών όπως η απόσβεση και η ακαμψία του ελατηρίου. - Έγγραφα

Μπορείτε να διαβάσετε περισσότερα σχετικά με αυτό από την τεκμηρίωση της Apple: //developer.apple.com/documentation/quartzcore/caspringanimation

Ας το εφαρμόσουμε στον υπάρχοντα κώδικα:

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 }

Η δουλειά μου τελείωσε εδώ.

Συνοπτικά, εδώ είναι μερικά από τα πλεονεκτήματα της χρήσης CA Animations:

  • Είναι εύκολο στη χρήση και την εφαρμογή
  • Υπάρχουν πολλές προσαρμογές διαθέσιμες
  • Είναι δυνατό να συγχρονίσετε πολλές κινούμενες εικόνες
  • Σχεδόν μηδενική χρήση CPU

Αυτά είναι μερικά μόνο από τα πλεονεκτήματα. Οι πιθανότητες είναι ατελείωτες.

Τώρα, όποτε έρχονται οι απαιτήσεις για κινούμενα σχέδια, αισθάνομαι σίγουρος ότι τα σχεδιάζω και τα εφαρμόζω. Και ελπίζω να αισθάνεστε επίσης με τον ίδιο τρόπο αφού το διαβάσετε αυτό.

Μη διστάσετε να αφήσετε προτάσεις ή σχόλια.