CAShapeLayer — τι είναι, ιδιότητες και δημιουργία σχημάτων

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-06-12 Χρόνος ανάγνωσης: 10 λεπ

CAShapeLayer — είναι μια υποκλάση της CALayer που προορίζεται για υλικό απόδοσης διανυσματικών περιγραμμάτων στην GPU. Σε αντίθεση με τη βασική CALayer που λειτουργεί με ψηφιδωτές εικόνες μέσω contents, η CAShapeLayer αποδίδει αυθαίρετα σχήματα που ορίζονται μέσω CGPath χωρίς δημιουργία ξεχωριστού offscreen buffer. Σύμφωνα με το Apple QuartzCore Documentation, 2025, η CAShapeLayer χρησιμοποιεί επιτάχυνση υλικού για εξομάλυνση άκρων και υποστηρίζει κινούμενα σχέδια path, strokeStart και strokeEnd. Είναι το τυπικό εργαλείο για δημιουργία εικονιδίων, δεικτών προόδου και μασκών στο iOS.

Κύρια Σημεία

  • CAShapeLayer — υποκλάση CALayer για απόδοση διανυσματικών σχημάτων στην GPU μέσω CGPath.
  • Η απόδοση περιγράμματος γίνεται υλικά χωρίς ενδιάμεσο ψηφιδωτό buffer — είναι ταχύτερη από την Core Graphics.
  • Ιδιότητες fillColor, strokeColor, lineWidth, lineCap, lineJoin ελέγχουν την εμφάνιση του σχήματος.
  • Κινούμενο σχέδιο path επιτρέπει την ομαλή μετατροπή ενός σχήματος σε άλλο — βασική δυνατότητα για κινούμενα σχέδια UI.
  • strokeStart και strokeEnd κινούνται για δημιουργία εφέ σχεδίασης περιγράμματος — ιδανικά για δείκτες φόρτωσης.

Τι είναι το CAShapeLayer;

CAShapeLayer — είναι ένα εξειδικευμένο στρώμα για απόδοση διανυσματικών γραφικών, που εισήχθη στο iOS 3.0. Σε αντίθεση με την CALayer που αποθηκεύει ψηφιδωτή εικόνα, η CAShapeLayer αποθηκεύει τη μαθηματική περιγραφή του περιγράμματος — CGPath — και την αποδίδει απευθείας στην GPU. Αυτό επιτρέπει κλιμάκωση του σχήματος χωρίς απώλεια ποιότητας και κίνηση των ιδιοτήτων του χωρίς επαναπόδοση περιεχομένου.

Αρχιτεκτονικά, η CAShapeLayer κληρονομεί όλες τις δυνατότητες της CALayer: σκιές, όρια, μετασχηματισμοί, μάσκες. Αλλά προσθέτει συγκεκριμένες ιδιότητες για εργασία με περιγράμματα: path, fillColor, strokeColor, lineWidth, lineCap, lineJoin, miterLimit, strokeStart, strokeEnd και fillRule. Κάθε μία από αυτές τις ιδιότητες μπορεί να κινηθεί μέσω CABasicAnimation.

Σύμφωνα με το Apple Documentation, η CAShapeLayer χρησιμοποιεί επιτάχυνση υλικού κατά την απόδοση. Σε αντίθεση με τη σχεδίαση μέσω Core Graphics στο drawRect:, όπου η CPU αποδίδει το περίγραμμα σε ψηφιδωτό περιβάλλον, η CAShapeLayer στέλνει εντολές απευθείας στην GPU μέσω Metal. Αποτέλεσμα — υψηλότερη απόδοση, ειδικά κατά τη διάρκεια κίνησης.

Η CAShapeLayer είναι ιδιαίτερα χρήσιμη για στοιχεία διεπαφής που αλλάζουν σχήμα ως απόκριση σε ενέργειες χρήστη: δείκτες προόδου, γραφήματα, εικονίδια tab-bar, μάσκες για κινούμενο σχέδιο εμφάνισης περιεχομένου.

Πώς αποδίδει η CAShapeLayer το περίγραμμα στην GPU

Η διαδικασία απόδοσης της CAShapeLayer διαφέρει από τη βασική CALayer. Αντί να αποθηκεύει ψηφιδωτό buffer με pixel, η CAShapeLayer στέλνει στην GPU την περιγραφή κορυφής του περιγράμματος — ένα σύνολο σημείων, καμπυλών Bezier και τμημάτων. Η GPU ψηφιοποιεί αυτό το περίγραμμα σε ένα πέρασμα, εφαρμόζοντας το χρώμα γεμίσματος και περιγράμματος στο στάδιο του fragment shader.

Αυτή η προσέγγιση δίνει δύο πλεονεκτήματα: κλιμάκωση χωρίς απώλεια ποιότητας (τα διανυσματικά γραφικά παραμένουν ευκρινή σε οποιαδήποτε ανάλυση) και αποδοτική κίνηση — όταν αλλάζει το path, η GPU υπολογίζει μόνο τα αλλαγμένα pixel, όχι ολόκληρη την οθόνη.

Βασικές Ιδιότητες CAShapeLayer

path — η κεντρική ιδιότητα της CAShapeLayer που δέχεται CGPath. Το περίγραμμα μπορεί να περιέχει γραμμές, τόξα, καμπύλες Bezier και ορθογώνια. Δημιουργείται μέσω UIBezierPath σε Swift ή CGPath σε Core Graphics. Παράδειγμα: UIBezierPath(roundedRect: rect, cornerRadius: 16).cgPath δημιουργεί στρογγυλεμένο ορθογώνιο.

  • fillColor — χρώμα γεμίσματος κλειστού περιγράμματος (CGColor). Αν nil — χωρίς γέμισμα. Υποστηρίζει κίνηση.
  • strokeColor — χρώμα περιγράμματος. Κινείται μαζί με lineWidth, δημιουργώντας εφέ σχεδίασης περιγράμματος.
  • lineWidth — πάχος γραμμής περιγράμματος σε σημεία. Προεπιλογή 1.0. Μπορεί να κινηθεί.
  • lineCap — στυλ άκρης γραμμής: .butt (ίσια κοπή), .round (στρογγυλεμένο), .square (ορθογώνιο με προεξοχή).
  • lineJoin — στυλ σύνδεσης γραμμών: .miter (κοφτή γωνία), .round (στρογγυλεμένο), .bevel (κομμένο).
  • strokeStart και strokeEnd — αναλογία σχεδιασμένου περιγράμματος από 0.0 έως 1.0. Η κίνηση strokeEnd δημιουργεί εφέ σταδιακής εμφάνισης.
  • fillRule — κανόνας γεμίσματος τεμνόμενων περιγραμμάτων: .nonZero (προεπιλογή) ή .evenOdd.
  • miterLimit — μέγιστο μήκος αιχμής όταν lineJoin = .miter. Αποτρέπει απείρως μακριές γωνίες.

Η ιδιότητα lineDashPattern επιτρέπει δημιουργία διακεκομμένων γραμμών. Δέχεται πίνακα αριθμών: [6, 3] σημαίνει 6 σημεία γραμμής και 3 σημεία διαστήματος. Το lineDashPhase ορίζει μετατόπιση μοτίβου και μπορεί να κινηθεί για εφέ κινούμενης διακεκομμένης γραμμής.

CAShapeLayer vs CALayer: πότε να επιλέξουμε κάθε

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

Η απόδοση επίσης διαφέρει. Η CALayer με cornerRadius και masksToBounds δημιουργεί offscreen buffer για περικοπή περιεχομένου, προσθέτοντας 2–5 ms ανά καρέ. Η CAShapeLayer δεν απαιτεί offscreen buffer — η περικοπή γίνεται σε επίπεδο vertex shader. Για στοιχεία με σύνθετη μάσκα, η CAShapeLayer μπορεί να είναι 2–3 φορές ταχύτερη.

  • CALayer: ορθογώνια στοιχεία, φωτογραφίες, βίντεο, περιεχόμενο με στρογγυλεμένες γωνίες (cornerRadius), σκιές, όρια.
  • CAShapeLayer: εικονίδια, γραφήματα, μπάρες προόδου, μάσκες αυθαίρετου σχήματος, κινούμενα περιγράμματα, σχήματα για κίνηση εμφάνισης.
  • CATextLayer: κείμενο που απαιτεί υποπίξελ απόδοση και προσωρινή αποθήκευση γλυφών.
  • CAGradientLayer: γεμίσματα διαβάθμισης — συνδυάζεται με CAShapeLayer μέσω mask για δημιουργία σχημάτων με διαβάθμιση.

Ο συνδυασμός CAShapeLayer με άλλα στρώματα είναι κοινό μοτίβο. Για παράδειγμα, η CAGradientLayer χρησιμοποιεί CAShapeLayer ως μάσκα για δημιουργία σχήματος με γέμισμα διαβάθμισης. Αυτή η προσέγγιση δίνει και διανυσματική ποιότητα και γέμισμα διαβάθμισης χωρίς απώλεια απόδοσης.

Κινούμενο σχέδιο CAShapeLayer: path και stroke

Κίνηση path — μία από τις ισχυρότερες δυνατότητες της CAShapeLayer. Αν και τα δύο περιγράμματα (αρχικό και τελικό) έχουν τον ίδιο αριθμό σημείων ελέγχου και τμημάτων, η Core Animation εκτελεί ομαλή παρεμβολή μεταξύ τους. Αποτέλεσμα — εφέ μεταμόρφωσης ενός σχήματος σε άλλο.

Προϋπόθεση συμβατότητας path: το αρχικό και τελικό UIBezierPath πρέπει να έχουν την ίδια δομή — ο αριθμός κλήσεων moveTo, addLine, addCurve και addQuadCurve πρέπει να συμπίπτει. Αν η δομή διαφέρει, η κίνηση θα είναι στιγμιαία, χωρίς παρεμβολή.

Σύμφωνα με το Apple WWDC 2024, ο συνδυασμός strokeStart και strokeEnd είναι το πιο συχνά χρησιμοποιούμενο μοτίβο κίνησης CAShapeLayer. Η κίνηση strokeEnd από 0.0 έως 1.0 δημιουργεί εφέ σχεδίασης περιγράμματος από την αρχή έως το τέλος. Χρησιμοποιείται σε δείκτες φόρτωσης, κινήσεις εμφάνισης γραφημάτων και προσαρμοσμένες μεταβάσεις μεταξύ οθονών.

Για δημιουργία εφέ παλμού, κίνησε ταυτόχρονα strokeEnd και opacity με διαφορετικές συναρτήσεις χρονισμού. Για εφέ κινούμενης διακεκομμένης γραμμής, κίνησε lineDashPhase με σταθερό lineDashPattern. Και οι δύο τεχνικές υλοποιούνται μέσω CABasicAnimation χωρίς συμμετοχή CPU.

Κίνηση ως μάσκα

Η CAShapeLayer χρησιμοποιείται συχνά ως mask για άλλα στρώματα. Για παράδειγμα, για κίνηση εμφάνισης περιεχομένου: στην αρχή mask.path είναι ορθογώνιο μηδενικού μεγέθους, στο τέλος — πλήρες μέγεθος. Η Core Animation παρεμβάλλει το path και το περιεχόμενο αποκαλύπτεται ομαλά.

Αυτό το μοτίβο χρησιμοποιείται στο iOS για κίνηση ανοίγματος καρτών, εμφάνισης παραθύρων και μεταβάσεων μεταξύ view controller. Σε αντίθεση με την κίνηση alpha, η κίνηση μέσω μάσκας CAShapeLayer δίνει πιο φυσικό εφέ εμφάνισης με αυθαίρετο σχήμα.

Παραδείγματα κώδικα με CAShapeLayer σε Swift

Πρώτο παράδειγμα — δημιουργία κυκλικού δείκτη προόδου με κίνηση strokeEnd. Αυτό είναι ένα τυπικό στοιχείο UI που δείχνει τις βασικές δυνατότητες της CAShapeLayer:

swift
func createProgressIndicator(in view: UIView) -> CAShapeLayer {
    let circlePath = UIBezierPath(
        arcCenter: CGPoint(x: 50, y: 50),
        radius: 40,
        startAngle: -.pi / 2,
        endAngle: 3 * .pi / 2,
        clockwise: true
    )

    let trackLayer = CAShapeLayer()
    trackLayer.path = circlePath.cgPath
    trackLayer.strokeColor = UIColor.systemGray5.cgColor
    trackLayer.fillColor = nil
    trackLayer.lineWidth = 8
    view.layer.addSublayer(trackLayer)

    let progressLayer = CAShapeLayer()
    progressLayer.path = circlePath.cgPath
    progressLayer.strokeColor = UIColor.systemBlue.cgColor
    progressLayer.fillColor = nil
    progressLayer.lineWidth = 8
    progressLayer.lineCap = .round
    progressLayer.strokeEnd = 0
    view.layer.addSublayer(progressLayer)

    return progressLayer
}

// Κίνηση στο 75%
progressLayer.animateStrokeEnd(to: 0.75, duration: 1.5)

Δεύτερο παράδειγμα — κίνηση μεταμόρφωσης μεταξύ κύκλου και τετραγώνου. Και τα δύο UIBezierPath έχουν συμβατή δομή:

swift
let morphLayer = CAShapeLayer()
morphLayer.fillColor = UIColor.systemPurple.cgColor
morphLayer.frame = rect

let circlePath = UIBezierPath(roundedRect: rect, cornerRadius: rect.width / 2)
let squarePath = UIBezierPath(roundedRect: rect, cornerRadius: 0)
morphLayer.path = circlePath.cgPath

let morphAnimation = CABasicAnimation(keyPath: "path")
morphAnimation.toValue = squarePath.cgPath
morphAnimation.duration = 0.6
morphAnimation.autoreverses = true
morphAnimation.repeatCount = .infinity
morphLayer.add(morphAnimation, forKey: "morph")

Τρίτο παράδειγμα — μάσκα με CAShapeLayer για κίνηση εμφάνισης περιεχομένου. Η μάσκα επεκτείνεται από το κέντρο προς τις άκρες:

swift
func revealContent(_ view: UIView) {
    let maskLayer = CAShapeLayer()
    let size = view.bounds.size.width * 1.5
    let center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)

    let initialPath = UIBezierPath(arcCenter: center, radius: 0, startAngle: 0, endAngle: .pi * 2, clockwise: true)
    let finalPath = UIBezierPath(arcCenter: center, radius: size, startAngle: 0, endAngle: .pi * 2, clockwise: true)

    maskLayer.path = initialPath.cgPath
    view.layer.mask = maskLayer

    let animation = CABasicAnimation(keyPath: "path")
    animation.toValue = finalPath.cgPath
    animation.duration = 0.4
    animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
    maskLayer.add(animation, forKey: "reveal")
    maskLayer.path = finalPath.cgPath
}

Συχνές Ερωτήσεις

Σε τι διαφέρει το CAShapeLayer από τη σχεδίαση στο drawRect;

Το drawRect χρησιμοποιεί CPU για απόδοση σε ψηφιδωτό περιβάλλον — είναι αργό για κινήσεις. Η CAShapeLayer αποδίδει το περίγραμμα στην GPU, δίνοντας 60 FPS σε κίνηση path, strokeEnd και μετασχηματισμών. Επιπλέον, η CAShapeLayer δεν απαιτεί επαναπόδοση κατά αλλαγή μεγέθους — το σχήμα κλιμακώνεται διανυσματικά.

Γιατί η κίνηση path δεν λειτουργεί ομαλά;

Η ομαλή κίνηση path απαιτεί ίδια δομή αρχικού και τελικού UIBezierPath. Ο αριθμός κλήσεων moveTo, addLine, addCurve πρέπει να συμπίπτει. Χρησιμοποίησε UIBezierPath με ίδιο αριθμό τμημάτων για αρχικό και τελικό σχήμα.

Πώς δημιουργείται διακεκομμένη γραμμή στο CAShapeLayer;

Όρισε lineDashPattern — πίνακα αριθμών που εναλλάξ καθορίζουν μήκος γραμμής και διαστήματος. Για παράδειγμα, [8, 4] δημιουργεί γραμμές 8pt με διαστήματα 4pt. Για κινούμενη διακεκομμένη γραμμή, κίνησε lineDashPhase μέσω CABasicAnimation με γραμμική συνάρτηση χρονισμού.

Μπορεί το CAShapeLayer να χρησιμοποιηθεί ως μάσκα;

Ναι, αυτό είναι ένα από τα κύρια σενάρια. Ανέθεσε CAShapeLayer στην ιδιότητα mask οποιασδήποτε CALayer, συμπεριλαμβανομένων CAGradientLayer και άλλων υποκλάσεων. Η κίνηση path της μάσκας δημιουργεί εφέ ομαλής εμφάνισης περιεχομένου μέσω σχήματος αυθαίρετης μορφής.

Πώς γεμίζεται ένα σχήμα με διαβάθμιση μέσω CAShapeLayer;

Δημιούργησε CAGradientLayer και όρισε mask = CAShapeLayer με το επιθυμητό path. Η διαβάθμιση θα είναι ορατή μόνο εντός του περιγράμματος της μάσκας. Αυτό το μοτίβο συνδυάζει τα πλεονεκτήματα διανυσματικού σχήματος CAShapeLayer με γέμισμα διαβάθμισης CAGradientLayer.

Περίληψη

  • CAShapeLayer — υποκλάση CALayer για υλική απόδοση διανυσματικών περιγραμμάτων στην GPU μέσω CGPath.
  • Βασικές ιδιότητες: path, fillColor, strokeColor, lineWidth, lineCap, lineJoin, strokeStart, strokeEnd.
  • Κίνηση path δημιουργεί μεταμόρφωση σχημάτων — απαιτεί ίδια δομή αρχικού και τελικού περιγράμματος.
  • Κίνηση strokeEnd — τυπικό μοτίβο για δείκτες προόδου και σχεδίαση περιγραμμάτων.
  • Η CAShapeLayer δεν απαιτεί offscreen buffer για κάλυψη, σε αντίθεση με CALayer με masksToBounds.
  • Χρησιμοποιείται ως μάσκα για CAGradientLayer, δημιουργώντας σχήματα με γέμισμα διαβάθμισης.
  • Για διακεκομμένες γραμμές χρησιμοποίησε lineDashPattern με κίνηση lineDashPhase για εφέ κίνησης.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης