viewDidAppear είναι μια μέθοδος του UIViewController που καλεί το UIKit αφού η οθόνη εμφανιστεί πλήρως στην οθόνη και ολοκληρωθούν όλα τα animations μετάβασης. Σύμφωνα με το Apple Developer Documentation, αυτή η μέθοδος εγγυάται ότι το View είναι ορατό στον χρήστη και έτοιμο για αλληλεπίδραση. viewDidAppear είναι το βέλτιστο σημείο για εκκίνηση animations, παρακολούθησης και ασύγχρονων λειτουργιών.
Βασικά σημεία
viewDidAppear είναι μια μέθοδος του UIViewController που καλεί το UIKit αφού το View προστεθεί στην ιεραρχία παραθύρων και το animation μετάβασης ολοκληρωθεί πλήρως. Αυτή τη στιγμή η οθόνη βρίσκεται στην τελική κατάσταση: είναι ορατή, μπορείτε να αλληλεπιδράσετε με αυτήν, όλα τα animations του UIKit έχουν σταματήσει. Ο προγραμματιστής παρακάμπτει αυτή τη μέθοδο για να εκτελέσει ενέργειες που απαιτούν η οθόνη να είναι εγγυημένα μπροστά στα μάτια του χρήστη.
Σε αντίθεση με το viewWillAppear, όπου η οθόνη απλώς προετοιμάζεται για προβολή, το viewDidAppear σηματοδοτεί ότι ο χρήστης βλέπει ήδη τη διεπαφή. Αυτή είναι μια κρίσιμη διαφορά: η εκκίνηση ενός animation στο viewWillAppear μπορεί να οδηγήσει σε χαμένα καρέ, καθώς το UIKit επεξεργάζεται ακόμα τη μετάβαση. Στο viewDidAppear η μετάβαση έχει ολοκληρωθεί και οι πόροι του controller μπορούν να χρησιμοποιηθούν για την απόδοση νέου περιεχομένου.
Η μέθοδος δέχεται την παράμετρο animated τύπου Bool, παρόμοια με το viewWillAppear. Εάν true — η εμφάνιση της οθόνης συνοδεύτηκε από animation. Αυτή η παράμετρος μπορεί να χρησιμοποιηθεί για την προσαρμογή της συμπεριφοράς UI: για παράδειγμα, για παράλειψη του εισερχόμενου animation κατά τη μη-ανιμαρισμένη επιστροφή.
viewDidAppear καλείται σε όλα τα σενάρια όταν η οθόνη έχει ολοκληρώσει τη διαδικασία εμφάνισης. Ας εξετάσουμε τις κύριες περιπτώσεις από την οπτική γωνία ενός προγραμματιστή iOS.
Αφού το UINavigationController ολοκληρώσει το animation push ή pop, στο στόχο controller καλείται το viewDidAppear. Για την πρώτη οθόνη στο stack, ενεργοποιείται μετά το αρχικό animation ανοίγματος. Αυτό είναι το κύριο σενάριο και σε αυτό αναφερόμαστε κατά την τοποθέτηση λογικής στο viewDidAppear.
Όταν ο χρήστης κλείνει έναν modal παρουσιαζόμενο controller και επιστρέφει στην προηγούμενη οθόνη, το UIKit καλεί το viewDidAppear στον επιστρέφοντα controller. Η παράμετρος animated θα αντιστοιχεί στο αν το dismiss εκτελέστηκε με animation. Αυτή η στιγμή είναι σημαντική για την ενημέρωση του UI μετά τη λήψη δεδομένων από τη θυγατρική οθόνη.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
logScreenView()
startOnboardingAnimation()
}
UITabBarController καλεί το viewDidAppear στον controller της επιλεγμένης καρτέλας μετά την ολοκλήρωση της εναλλαγής. Αυτή είναι η διαφορά από το viewWillAppear, που ενεργοποιείται στην αρχή της εναλλαγής. Εάν στην καρτέλα υπάρχει animation υποδοχής ή πρέπει να παρακολουθείται ο ενεργός χρόνος, το viewDidAppear είναι το κατάλληλο σημείο.
Όταν η εφαρμογή επιστρέφει από background σε foreground, μπορεί να κληθούν τα viewWillAppear και viewDidAppear στον ορατό controller, εάν ο κύκλος ζωής του View είχε προσωρινά ανασταλεί. Ωστόσο, για αξιόπιστη παρακολούθηση της επιστροφής από το παρασκήνιο, χρησιμοποιήστε ξεχωριστά το UIApplication.willEnterForegroundNotification.
viewDidAppear επιλύει εργασίες που απαιτούν ορατή οθόνη για σωστή εκτέλεση. Ας εξετάσουμε τα βασικά σενάρια χρήσης σε πραγματικά έργα.
Η πιο συνηθισμένη εργασία του viewDidAppear — παρακολούθηση προβολής οθόνης. Τα αναλυτικά συστήματα όπως τα Firebase Analytics, Amplitude ή Mixpanel πρέπει να λαμβάνουν συμβάντα μόνο αφού η οθόνη εμφανιστεί πραγματικά στον χρήστη. Η αποστολή συμβάντος στο viewWillAppear μπορεί να μειώσει τον χρόνο προβολής και να δημιουργήσει ψευδείς ενεργοποιήσεις.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
Analytics.logEvent(
name: "screen_view",
parameters: [
"screen_name": "ProfileScreen",
"screen_class": String(describing: self)
]
)
}
Animations που πρέπει να ξεκινήσουν μετά την εμφάνιση της οθόνης — εμφάνιση στοιχείων με καθυστέρηση, παράλλαξη, εκμάθηση — εκκινούνται στο viewDidAppear. Αυτή τη στιγμή το γραφικό περιβάλλον είναι πλήρως έτοιμο και το animation θα είναι ομαλό, χωρίς απώλεια καρέ στην αρχή. Αυτό είναι ιδιαίτερα σημαντικό για animations που χρησιμοποιούν το UIViewPropertyAnimator.
Βαρείς ασύγχρονες λειτουργίες — φόρτωση εικόνων υψηλής ανάλυσης, ανάλυση μεγάλων JSON, αρχικοποίηση βίντεο — είναι καλύτερο να εκκινούνται στο viewDidAppear παρά στο viewDidLoad ή viewWillAppear. Τη στιγμή της κλήσης της μεθόδου, ο χρήστης βλέπει ήδη τη διεπαφή, οπότε μπορεί να εμφανιστεί ένας σκελετός ή loader, χωρίς να καθυστερήσει την εμφάνιση της οθόνης.
Εάν στην οθόνη υπάρχουν στοιχεία που απαιτούν περιοδική ενημέρωση — χρονόμετρο αντίστροφης μέτρησης, δείκτης φόρτωσης, animation προόδου — εκκινούνται στο viewDidAppear και σταματούν στο viewDidDisappear. Αυτό αποτρέπει τη λειτουργία χρονομέτρων όταν η οθόνη δεν είναι ορατή, εξοικονομώντας μπαταρία και πόρους CPU.
Περιεχόμενο πολυμέσων — βίντεο, ήχος, animations Lottie — εκκινείται ακριβώς στο viewDidAppear, όχι νωρίτερα. Εάν ξεκινήσετε την αναπαραγωγή στο viewWillAppear, ο χρήστης θα χάσει τα πρώτα δευτερόλεπτα ενώ η οθόνη εμφανίζεται ακόμα. Στο viewDidAppear μπορείτε να ξεκινήσετε το AVPlayer ή το animation Lottie με τη βεβαιότητα ότι ο χρήστης βλέπει το περιεχόμενο από το πρώτο καρέ. Αυτό είναι ιδιαίτερα σημαντικό για οθόνες onboarding και splash screens, όπου ο ακριβής χρονισμός έχει σημασία.
Η σωστή στιγμή εκκίνησης ενός animation επηρεάζει άμεσα την αντίληψη της ομαλότητας της διεπαφής. Η διαφορά μεταξύ εκκίνησης στο viewWillAppear και στο viewDidAppear μπορεί να είναι ανεπαίσθητη σε απλά animations, αλλά κρίσιμη για σύνθετες σκηνές.
Όταν το UIKit εκτελεί μια push μετάβαση μεταξύ οθονών, δημιουργεί στιγμιότυπα οθόνης, τα ανιμάρει και ταυτόχρονα καλεί το viewWillAppear στον νέο controller. Εάν αυτή τη στιγμή εκκινήσετε ένα βαρύ animation — παράλλαξη, θάμπωμα, μετασχηματισμό — το UIKit μπορεί να παραλείψει καρέ του animation μετάβασης, δημιουργώντας ένα εφέ τραντάγματος. Το viewDidAppear εγγυάται ότι το animation μετάβασης έχει ολοκληρωθεί και έχετε πλήρη έλεγχο της απόδοσης.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(
withDuration: 0.6,
delay: 0.3,
usingSpringWithDamping: 0.8,
initialSpringVelocity: 0.5
) {
self.cardView.alpha = 1.0
self.cardView.transform = .identity
}
}
Χρησιμοποιήστε καθυστερήσεις και απόσβεση για να δημιουργήσετε μια φυσική εμφάνιση στοιχείων σε ακολουθία. Αυτή η προσέγγιση βελτιώνει την αντίληψη της διεπαφής και αυξάνει τον χρόνο παραμονής — ο χρήστης μελετά το περιεχόμενο περισσότερο, γεγονός που επηρεάζει θετικά τις μετρήσεις συμπεριφοράς.
Εσφαλμένη χρήση του viewDidAppear μπορεί να οδηγήσει σε προβλήματα απόδοσης, απροσδόκητη συμπεριφορά animations και υπερβολική παρακολούθηση. Ας εξετάσουμε συνηθισμένα λάθη.
Πρώτο λάθος — πολλαπλές κλήσεις. Το viewDidAppear μπορεί να κληθεί πολλές φορές σε ορισμένα σενάρια: εναλλαγή καρτελών, επιστροφή από παρασκήνιο, modal μεταβάσεις. Εάν μια βαριά λειτουργία εκτελείται στη μέθοδο χωρίς έλεγχο σημαίας, θα διπλασιαστεί. Για ενέργειες μίας χρήσης, χρησιμοποιήστε τη σημαία hasAppeared ή το dispatchOnce.
Δεύτερο λάθος — εκκίνηση αιτημάτων δικτύου χωρίς ακύρωση κατά την απόκρυψη. Εάν ο χρήστης εγκαταλείψει την οθόνη πριν την ολοκλήρωση του αιτήματος, το αποτέλεσμα μπορεί να εφαρμοστεί σε ένα ήδη κρυφό View. Χρησιμοποιήστε ακυρώσιμες URLSessionTask και τερματίστε τις στο viewDidDisappear.
Τρίτο λάθος — παρακολούθηση στο viewWillAppear αντί για viewDidAppear. Ορισμένοι προγραμματιστές στέλνουν συμβάντα analytics στο viewWillAppear, αλλά αυτό δημιουργεί ψευδείς ενεργοποιήσεις εάν η οθόνη δεν εμφανίστηκε (π.χ., σε ακυρωμένη χειρονομία pop). Το viewDidAppear είναι ο μόνος αξιόπιστος δείκτης ότι ο χρήστης είδε πραγματικά την οθόνη.
Τέταρτο λάθος — ξεχάσατε το super. Η κλήση super.viewDidAppear είναι απαραίτητη για τη σωστή λειτουργία των UINavigationController, UITabBarController και UISplitViewController. Χωρίς αυτήν, οι τυπικοί μηχανισμοί πλοήγησης και ενημέρωσης διεπαφής μπορεί να σπάσουν.
Πέμπτο λάθος — αλλαγή προσανατολισμού ή μεγέθους οθόνης χωρίς να ληφθεί υπόψη το viewDidLayoutSubviews. Εάν το animation σας στο viewDidAppear εξαρτάται από τα τελικά μεγέθη του View, θυμηθείτε ότι το viewDidLayoutSubviews μπορεί να κληθεί πολλές φορές πριν από το viewDidAppear. Κατά την πρώτη εμφάνιση της οθόνης, η διάταξη ολοκληρώνεται πριν από την κλήση του viewDidAppear, αλλά σε μεταγενέστερες αλλαγές μεγέθους — για παράδειγμα, κατά την περιστροφή της συσκευής — το viewDidAppear μπορεί να μην κληθεί και το animation σας δεν θα ξεκινήσει. Σε τέτοιες περιπτώσεις, χρησιμοποιήστε το viewDidLayoutSubviews με έλεγχο της σημαίας firstLayout.
Η σωστή υλοποίηση περιλαμβάνει τη διατήρηση αναφοράς στο αντικείμενο animation και τη ρητή ακύρωσή του κατά την αποχώρηση από την οθόνη. Έκτο λάθος — εκκίνηση ατελείωτων animations χωρίς σημαία διακοπής. Εάν στο viewDidAppear εκκινήσετε ένα επαναλαμβανόμενο animation (π.χ., παλλόμενο δείκτη ή περιστρεφόμενο loader), αλλά δεν το σταματήσετε στο viewDidDisappear, το animation θα καταναλώνει πόρους GPU ακόμα και όταν η οθόνη είναι κρυφή. Πάντα να διατηρείτε αναφορά στο ενεργό animation και να καλείτε removeAllAnimations ή setCompletion στην αντίστοιχη μέθοδο τερματισμού του κύκλου ζωής.
Έβδομο λάθος — αγνόηση του viewDidDisappear για τη διακοπή δραστηριοτήτων. Εάν ξεκινήσατε την παρακολούθηση GPS, επιταχυνσιόμετρου ή γυροσκοπίου στο viewDidAppear, φροντίστε να τη σταματήσετε στο viewDidDisappear. Διαφορετικά, οι αισθητήρες θα συνεχίσουν να λειτουργούν στο παρασκήνιο, καταναλώνοντας μπαταρία, ακόμα κι αν ο χρήστης έχει μεταβεί εδώ και καιρό σε άλλη οθόνη. Χρησιμοποιήστε ζευγαρωμένες κλήσεις start και stop στις αντίστοιχες μεθόδους του κύκλου ζωής — αυτό εγγυάται τη σωστή διαχείριση των πόρων της συσκευής.
Συχνές Ερωτήσεις
viewWillAppear καλείται πριν από το animation εμφάνισης, όταν η οθόνη δεν είναι ακόμα ορατή. Το viewDidAppear — μετά την πλήρη ολοκλήρωση του animation, όταν η οθόνη είναι ορατή και διαθέσιμη για αλληλεπίδραση.
Στο viewDidAppear το animation μετάβασης του UIKit έχει ήδη ολοκληρωθεί και όλοι οι πόροι απόδοσης είναι διαθέσιμοι για τον controller σας. Η εκκίνηση του animation νωρίτερα μπορεί να οδηγήσει σε χαμένα καρέ και τρανταχτή διεπαφή.
Σε κανονικό κύκλο ζωής όχι — το viewDidAppear ακολουθεί πάντα το viewWillAppear. Ωστόσο, σε ορισμένα σενάρια επαναφοράς κατάστασης, το σύστημα μπορεί να καλέσει μόνο το viewDidAppear.
Προσθέστε έλεγχο σημαίας firstAppearance ή χρησιμοποιήστε συνδυασμό μετρητή και ονόματος οθόνης. Για παράδειγμα, στείλτε το συμβάν screen_view μόνο όταν firstAppearance = true, στη συνέχεια επαναφέρετε τη σημαία.
Κατά την επιστροφή από το παρασκήνιο, το UIKit μπορεί να καλέσει το viewDidAppear στον ορατό controller, εάν το View έχει εκφορτωθεί από τη μνήμη. Για αξιόπιστη παρακολούθηση, χρησιμοποιήστε τις ειδοποιήσεις AppDelegate.
Περίληψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης