UIViewController — η κεντρική κλάση της εφαρμογής iOS, που διαχειρίζεται την οθόνη και το περιεχόμενό της. Κάθε οθόνη iPhone ή iPad διαχειρίζεται από ένα ViewController, το οποίο συντονίζει την εμφάνιση, τον κύκλο ζωής και την πλοήγηση. Διαβάστε περισσότερα για την αρχιτεκτονική UIKit στην επίσημη τεκμηρίωση της Apple.
Κύρια σημεία
UIViewController — μια κλάση από το πλαίσιο UIKit που διαχειρίζεται την ιεραρχία UIView και συντονίζει την εμφάνιση δεδομένων στην οθόνη. Κάθε εφαρμογή iOS περιέχει τουλάχιστον ένα ViewController — τον ριζικό ελεγκτή του παραθύρου. Ο ελεγκτής χειρίζεται περιστροφές οθόνης, μεταβάσεις μεταξύ οθονών και γεγονότα κύκλου ζωής.
Η αρχιτεκτονική MVC (Model-View-Controller) στο iOS υλοποιείται ακριβώς μέσω του UIViewController: ο ελεγκτής λαμβάνει δεδομένα από το μοντέλο και ενημερώνει την προβολή. Το ViewController δεν είναι οπτικό στοιχείο — διαχειρίζεται την ιδιότητα view που περιέχει την ιεραρχία subview. Σύμφωνα με δεδομένα της Apple (2026), το UIKit περιέχει πάνω από 40 ενσωματωμένες υποκλάσεις του UIViewController.
Το πρώτο iPhone SDK (2008) περιλάμβανε το UIViewController με τρεις μεθόδους κύκλου ζωής. Σε 18 χρόνια, η Apple πρόσθεσε υποστήριξη για Container View Controller, προσαρμοστικές παρουσιάσεις, UIViewControllerTransitioningDelegate για προσαρμοσμένες κινούμενες εικόνες και λειτουργία διαιρεμένης οθόνης στο iPad. Το UIViewController παραμένει υποχρεωτικό συστατικό για εφαρμογές UIKit.
Ο κύκλος ζωής του UIViewController — μια ακολουθία μεθόδων που καλούνται από το σύστημα κατά τη δημιουργία, εμφάνιση και απόκρυψη της οθόνης. Η κατανόηση του κύκλου ζωής είναι κρίσιμη: η λανθασμένη τοποθέτηση κώδικα οδηγεί σε διαρροές μνήμης, περιττά αιτήματα δικτύου και τρεμόπαιγμα διεπαφής.
| Μέθοδος | Στιγμή κλήσης | Σκοπός |
|---|---|---|
| viewDidLoad | Μία φορά, μετά τη φόρτωση view στη μνήμη | Αρχική ρύθμιση UI, εγγραφή Combine |
| viewWillAppear | Πριν από την εμφάνιση της οθόνης | Ενημέρωση δεδομένων, απόκρυψη/εμφάνιση navigation bar |
| viewDidAppear | Μετά την εμφάνιση της οθόνης | Εκκίνηση κινουμένων σχεδίων, αναλυτικά, ενημέρωση κάμερας |
| viewWillDisappear | Πριν από την αποχώρηση από την οθόνη | Αποθήκευση προχείρων, διαγραφή από ειδοποιήσεις |
| viewDidDisappear | Μετά την αποχώρηση από την οθόνη | Διακοπή βαριών διεργασιών, απελευθέρωση πόρων |
Κατά την πρώτη εμφάνιση οθόνης: init → loadView → viewDidLoad → viewWillAppear → viewDidAppear. Κατά την εκ νέου εμφάνιση (επιστροφή από άλλη οθόνη): viewWillAppear → viewDidAppear. Το viewDidLoad καλείται μόνο μία φορά κατά τη διάρκεια ζωής του ελεγκτή.
Η μέθοδος viewDidLoad — το κύριο σημείο ρύθμισης της διεπαφής χρήστη. Καλείται μετά τη φόρτωση του view στη μνήμη, όταν όλα τα IBOutlet είναι ήδη συνδεδεμένα. Εδώ δημιουργούνται τα στοιχεία UI προγραμματιστικά, ρυθμίζονται οι περιορισμοί, φορτώνονται τα αρχικά δεδομένα.
final class ProfileViewController: UIViewController {
private let tableView = UITableView()
private let viewModel = ProfileViewModel()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
bindViewModel()
}
private func setupUI() {
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
tableView.register(ProfileCell.self,
forCellReuseIdentifier: ProfileCell.reuseId)
}
private func bindViewModel() {
viewModel.$user
.receive(on: DispatchQueue.main)
.sink { [weak self] user in
self?.title = user.name
}
.store(in: &cancellables)
}
}Στο SwiftUI αυτός ο κώδικας είναι ισοδύναμος με το σώμα του View. Αλλά το UIViewController δίνει πλήρη έλεγχο πάνω στον κύκλο ζωής και τη βελτιστοποίηση. Το bindViewModel χρησιμοποιεί Combine για αντιδραστική εγγραφή — τα δεδομένα ενημερώνονται αυτόματα όταν αλλάζει το μοντέλο.
Το viewWillAppear καλείται κάθε φορά πριν από την εμφάνιση της οθόνης, ακόμα κι αν ήταν ήδη στη μνήμη. Εδώ γίνεται η ενημέρωση δεδομένων που μπορεί να έχουν αλλάξει σε άλλη οθόνη: επαναφόρτωση λίστας, ενημέρωση μετρητή ειδοποιήσεων, ρύθμιση navigation bar για συγκεκριμένη οθόνη.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Απόκρυψη navigation bar σε αυτήν την οθόνη
navigationController?.setNavigationBarHidden(true, animated: animated)
// Ενημέρωση δεδομένων κατά την επιστροφή από άλλη οθόνη
tableView.reloadData()
badgeLabel.text = "\(CartManager.shared.itemCount)"
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Αναλυτικά: μόνο αφού ο χρήστης είδε την οθόνη
AnalyticsService.shared.logScreenView("Profile")
}Η διαφορά μεταξύ viewDidLoad και viewWillAppear είναι κρίσιμη: το viewDidLoad εκτελείται μία φορά και είναι κατάλληλο για στατική ρύθμιση, το viewWillAppear — κάθε φορά κατά την εμφάνιση, κατάλληλο για δυναμικές ενημερώσεις. Η τοποθέτηση αιτημάτων δικτύου στο viewDidLoad θα οδηγήσει σε εμφάνιση παλιών δεδομένων κατά την επιστροφή στην οθόνη.
Container View Controller — ένας ViewController που διαχειρίζεται έναν ή περισσότερους θυγατρικούς ViewController. Η Apple παρέχει τρία ενσωματωμένα κοντέινερ: UINavigationController (στοίβα οθονών), UITabBarController (καρτέλες) και UISplitViewController (master-detail για iPad).
Το UINavigationController οργανώνει μεταβάσεις σε στοίβα — το push προσθέτει οθόνη, το pop αφαιρεί. Το UITabBarController εναλλάσσεται μεταξύ ανεξάρτητων τμημάτων της εφαρμογής. Το UISplitViewController εμφανίζει δύο ελεγκτές δίπλα-δίπλα στο iPad και έναν στο iPhone. Ο προγραμματιστής μπορεί να δημιουργήσει το δικό του κοντέινερ μέσω addChild.
// Προσαρμοσμένο Container View Controller
final class ContainerViewController: UIViewController {
private let sidebarVC = SidebarViewController()
private let contentVC = ContentViewController()
override func viewDidLoad() {
super.viewDidLoad()
// Προσθήκη θυγατρικού ελεγκτή
addChild(sidebarVC)
view.addSubview(sidebarVC.view)
sidebarVC.didMove(toParent: self)
addChild(contentVC)
view.addSubview(contentVC.view)
contentVC.didMove(toParent: self)
}
}Η σωστή εργασία με Container View Controller απαιτεί κλήση addChild, προσθήκη view και didMove(toParent:) με αυτή τη σειρά. Κατά την αφαίρεση — willMove(toParent: nil), removeFromSuperview, removeFromParent. Η παραβίαση της σειράς οδηγεί σε διαρροές μνήμης.
Το πρόβλημα του Massive View Controller — όταν το UIViewController περιέχει εκατοντάδες γραμμές κώδικα με επιχειρηματική λογική, αιτήματα δικτύου, πλοήγηση και κώδικα UI. Η Apple γνωρίζει το πρόβλημα και συνιστά MVVM (Model-View-ViewModel) μαζί με Coordinator για τον διαχωρισμό της πλοήγησης.
Το MVVM μεταφέρει την επιχειρηματική λογική από τον ελεγκτή στο ViewModel. Ο Controller απλώς συνδέει το ViewModel με το View μέσω Combine ή delegate. Ο Coordinator μεταφέρει τη λογική πλοήγησης — δημιουργία και μεταβάσεις μεταξύ ελεγκτών — σε ξεχωριστή κλάση. Αυτή η προσέγγιση έχει ενσωματωθεί στις βέλτιστες πρακτικές της Apple από το 2024.
// Coordinator — διαχείριση πλοήγησης
protocol Coordinator {
var childCoordinators: [Coordinator] { get set }
func start()
}
final class MainCoordinator: Coordinator {
var childCoordinators = [Coordinator]()
private let navigationController: UINavigationController
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
let vc = ListViewController()
vc.didSelectItem = { [weak self] item in
self?.showDetail(item)
}
navigationController.pushViewController(vc, animated: false)
}
private func showDetail(_ item: Item) {
let vc = DetailViewController(item: item)
navigationController.pushViewController(vc, animated: true)
}
}Η επιλογή μεταξύ UIViewController και SwiftUI View εξαρτάται από το έτος έναρξης του έργου, τις απαιτήσεις προσαρμογής και την ελάχιστη υποστηριζόμενη έκδοση iOS. Το UIKit με UIViewController παραμένει η βάση για έργα που ξεκίνησαν πριν από το 2020 και για εφαρμογές με βαθιά προσαρμογή διεπαφής.
Το SwiftUI είναι κατάλληλο για νέα έργα με iOS 17+, τυπικές διεπαφές και πρωτότυπα. Ωστόσο, για προσαρμοσμένες μεταβάσεις, εργασία με κάμερα, MapKit, σύνθετα κινούμενα σχέδια CALayer απαιτείται UIViewController. Η Apple συνιστά τον συνδυασμό προσεγγίσεων μέσω UIHostingController (SwiftUI εντός UIKit) και UIViewRepresentable (UIKit εντός SwiftUI).
| Σενάριο | UIKit (UIViewController) | SwiftUI (View) |
|---|---|---|
| Προσαρμοσμένη κίνηση | Πλήρης έλεγχος μέσω UIViewPropertyAnimator | Περιορισμένη μέσω Animation |
| Εργασία με κάμερα | AVCaptureSession + UIViewPreview | Μέσω UIViewControllerRepresentable |
| CollectionView | UICollectionView + UICollectionViewLayout | LazyVGrid/LazyHGrid |
| Προσαρμογή iPad | UISplitViewController + UITraitCollection | NavigationSplitView + sizeClass |
| Ταχύτητα ανάπτυξης | Πιο αργή (χειροκίνητη διάταξη) | Πιο γρήγορη (δηλωτική) |
Συχνές Ερωτήσεις
UIViewController — ελεγκτής που διαχειρίζεται την οθόνη και τον κύκλο ζωής της. UIView — προβολή που εμφανίζει περιεχόμενο. Το ViewController περιέχει ιεραρχία UIView, αλλά δεν είναι το ίδιο οπτικό στοιχείο. Ένας ελεγκτής διαχειρίζεται πολλές προβολές.
Massive View Controller — αντπρότυπο όταν το UIViewController περιέχει υπερβολικά πολλή λογική: δεδομένα, πλοήγηση, αιτήματα δικτύου, κινούμενα σχέδια. Λύση — διαχωρισμός κώδικα σε ξεχωριστές υπηρεσίες, συντονιστές και ViewModel (MVVM).
Τέσσερις τρόποι: μέσω ιδιότητας στο prepare(for:sender:) (Segue), μέσω Delegate, μέσω Closure, μέσω κοινόχρηστης υπηρεσίας. Για χαλαρή σύζευξη χρησιμοποιείται Coordinator + Delegate ή Combine.
Container View Controller — ελεγκτής που διαχειρίζεται θυγατρικούς ViewController. Παραδείγματα: UINavigationController, UITabBarController, UISplitViewController. Ο γονικός ελεγκτής προσθέτει παιδιά μέσω addChild, εναλλάσσεται μεταξύ τους και διαχειρίζεται τη διάταξή τους.
UIViewController — για σύνθετες προσαρμοσμένες κινήσεις, εργασία με κάμερα, χάρτη, βίντεο, UICollectionView με προσαρμοσμένη διάταξη. SwiftUI View — για τυπικές διεπαφές iOS 13+. Επιτρέπεται συνδυασμός μέσω UIHostingController.
Περίληψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης