UIViewController, iOS uygulamalarının merkezi sınıfıdır ve ekranı ve içeriğini yönetir. Her iPhone veya iPad ekranı, görüntüleme, yaşam döngüsü ve navigasyonu koordine eden bir ViewController tarafından yönetilir. UIKit mimarisi hakkında daha fazla bilgi için Apple'ın resmi belgelerine bakın.
Önemli Noktalar
UIViewController, UIKit framework'ünden bir sınıftır ve UIView hiyerarşisini yönetir ve verilerin ekranda görüntülenmesini koordine eder. Her iOS uygulaması en az bir ViewController içerir — pencerenin kök denetleyicisi. Denetleyici, ekran döndürmelerini, ekranlar arası geçişleri ve yaşam döngüsü olaylarını işler.
iOS'taki MVC (Model-View-Controller) mimarisi tam olarak UIViewController aracılığıyla uygulanır: denetleyici modelden veri alır ve görünümü günceller. Bir ViewController görsel bir öğe değildir — subview hiyerarşisini içeren view özelliğini yönetir. Apple'a (2026) göre UIKit, 40'tan fazla yerleşik UIViewController alt sınıfı içerir.
İlk iPhone SDK (2008), üç yaşam döngüsü yöntemiyle UIViewController'ı içeriyordu. 18 yıl içinde Apple, Container View Controller, uyarlanabilir sunumlar, özel animasyonlar için UIViewControllerTransitioningDelegate ve iPad'de bölünmüş ekran modu desteği ekledi. UIViewController, UIKit uygulamaları için zorunlu bir bileşen olmaya devam ediyor.
UIViewController'ın yaşam döngüsü, bir ekran oluşturulurken, görüntülenirken ve gizlenirken sistem tarafından çağrılan yöntemler dizisidir. Lifecycle'ı anlamak kritik derecede önemlidir: kodun yanlış yerleştirilmesi bellek sızıntılarına, gereksiz ağ isteklerine ve arayüz titremesine yol açar.
| Yöntem | Çağrılma Anı | Amaç |
|---|---|---|
| viewDidLoad | Bir kez, view belleğe yüklendikten sonra | İlk UI kurulumu, Combine aboneliği |
| viewWillAppear | Ekran görünmeden önce | Veri güncelleme, navigasyon çubuğunu gizleme/gösterme |
| viewDidAppear | Ekran göründükten sonra | Animasyonları başlatma, analitik, kamera güncelleme |
| viewWillDisappear | Ekrandan ayrılmadan önce | Taslakları kaydetme, bildirim aboneliğini iptal etme |
| viewDidDisappear | Ekrandan ayrıldıktan sonra | Ağır işlemleri durdurma, kaynakları serbest bırakma |
Ekranın ilk görüntülenmesinde sıra: init → loadView → viewDidLoad → viewWillAppear → viewDidAppear. Tekrar görünmede (başka bir ekrandan dönüş): viewWillAppear → viewDidAppear. viewDidLoad, denetleyicinin ömrü boyunca yalnızca bir kez çağrılır.
viewDidLoad yöntemi, kullanıcı arayüzünü yapılandırmak için ana noktadır. View belleğe yüklendikten sonra, tüm IBOutlet bağlantıları zaten kurulmuşken çağrılır. Burada UI öğeleri programlı olarak oluşturulur, kısıtlamalar yapılandırılır ve ilk veriler yüklenir.
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'de bu kod, View'ın body'sine eşdeğerdir. Ancak UIViewController, yaşam döngüsü ve optimizasyon üzerinde tam kontrol sağlar. bindViewModel, reaktif abonelik için Combine kullanır — model değiştiğinde veriler otomatik olarak güncellenir.
viewWillAppear, ekran zaten bellekte olsa bile, görünmeden önce her seferinde çağrılır. Burası, başka bir ekranda değişmiş olabilecek verileri güncelleme yeridir: bir listeyi yeniden yükleme, bildirim rozetini güncelleme, belirli bir ekran için navigasyon çubuğunu yapılandırma.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Bu ekranda navigasyon çubuğunu gizle
navigationController?.setNavigationBarHidden(true, animated: animated)
// Başka bir ekrandan dönerken verileri güncelle
tableView.reloadData()
badgeLabel.text = "\(CartManager.shared.itemCount)"
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Analitik: yalnızca kullanıcı ekranı gördükten sonra
AnalyticsService.shared.logScreenView("Profile")
}viewDidLoad ve viewWillAppear arasındaki fark kritiktir: viewDidLoad bir kez çalıştırılır ve statik kurulum için uygundur, viewWillAppear ekran her görüntülendiğinde çalıştırılır ve dinamik güncellemeler için uygundur. viewDidLoad'a ağ istekleri yerleştirmek, ekrana dönüldüğünde eski verilerin gösterilmesine neden olur.
Container View Controller, bir veya daha fazla alt ViewController'ı yöneten bir ViewController'dır. Apple üç yerleşik kapsayıcı sağlar: UINavigationController (ekran yığını), UITabBarController (sekmeler) ve UISplitViewController (iPad için master-detail).
UINavigationController, geçişleri bir yığında düzenler — push ekran ekler, pop kaldırır. UITabBarController, uygulamanın bağımsız bölümleri arasında geçiş yapar. UISplitViewController, iPad'de iki denetleyiciyi yan yana ve iPhone'da birini gösterir. Geliştirici, addChild aracılığıyla özel bir kapsayıcı oluşturabilir.
// Özel Container View Controller
final class ContainerViewController: UIViewController {
private let sidebarVC = SidebarViewController()
private let contentVC = ContentViewController()
override func viewDidLoad() {
super.viewDidLoad()
// Alt denetleyici ekleme
addChild(sidebarVC)
view.addSubview(sidebarVC.view)
sidebarVC.didMove(toParent: self)
addChild(contentVC)
view.addSubview(contentVC.view)
contentVC.didMove(toParent: self)
}
}Container View Controller ile doğru çalışma, addChild, view ekleme ve didMove(toParent:) öğelerini bu sırayla çağırmayı gerektirir. Kaldırma sırasında: willMove(toParent: nil), removeFromSuperview, removeFromParent. Sırayı ihlal etmek bellek sızıntılarına yol açar.
Massive View Controller sorunu, bir UIViewController'ın iş mantığı, ağ istekleri, navigasyon ve UI koduyla yüzlerce satır kod içermesiyle ortaya çıkar. Apple sorunu kabul eder ve navigasyonu çıkarmak için Coordinator ile birlikte MVVM (Model-View-ViewModel) önerir.
MVVM, iş mantığını denetleyiciden bir ViewModel'e taşır. Controller, ViewModel'i Combine veya bir temsilci aracılığıyla yalnızca View'a bağlar. Coordinator, navigasyon mantığını — denetleyiciler arasında oluşturma ve geçiş yapma — ayrı bir sınıfa çıkarır. Bu yaklaşım 2024'ten beri Apple en iyi uygulamalarına dahil edilmiştir.
// Coordinator — navigasyon yönetimi
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 ve SwiftUI View arasındaki seçim, projenin başlangıç yılına, özelleştirme gereksinimlerine ve desteklenen minimum iOS sürümüne bağlıdır. UIKit ve UIViewController, 2020'den önce başlatılan projeler ve derin arayüz özelleştirmesi olan uygulamalar için temel olmaya devam ediyor.
SwiftUI, iOS 17+ ile yeni projeler, standart arayüzler ve prototipler için uygundur. Ancak özel geçişler, kamera çalışması, MapKit, karmaşık CALayer animasyonları UIViewController gerektirir. Apple, UIHostingController (UIKit içinde SwiftUI) ve UIViewRepresentable (SwiftUI içinde UIKit) aracılığıyla yaklaşımları birleştirmeyi önerir.
| Senaryo | UIKit (UIViewController) | SwiftUI (View) |
|---|---|---|
| Özel animasyon | UIViewPropertyAnimator ile tam kontrol | Animation ile sınırlı |
| Kamera çalışması | AVCaptureSession + UIViewPreview | UIViewControllerRepresentable aracılığıyla |
| CollectionView | UICollectionView + UICollectionViewLayout | LazyVGrid/LazyHGrid |
| iPad uyarlaması | UISplitViewController + UITraitCollection | NavigationSplitView + sizeClass |
| Geliştirme hızı | Daha yavaş (manuel düzen) | Daha hızlı (bildirimsel) |
Sıkça Sorulan Sorular
UIViewController, ekranı ve yaşam döngüsünü yöneten bir denetleyicidir. UIView, içeriği görüntüleyen bir görünümdür. Bir ViewController, UIViews hiyerarşisi içerir ancak kendisi görsel bir öğe değildir. Bir denetleyici birden çok görünümü yönetir.
Massive View Controller, UIViewController'ın çok fazla mantık içerdiği bir anti-kalıptır: veri, navigasyon, ağ istekleri, animasyon. Çözüm — kodu ayrı hizmetlere, koordinatörlere ve ViewModel'e (MVVM) çıkarmaktır.
Dört yol: prepare(for:sender:) (Segue) içinde bir özellik aracılığıyla, bir temsilci (Delegate) aracılığıyla, bir kapatma (Closure) aracılığıyla, paylaşılan bir hizmet aracılığıyla. Gevşek bağlantı için Coordinator + Delegate veya Combine kullanın.
Container View Controller, alt ViewController'ları yöneten bir denetleyicidir. Örnekler: UINavigationController, UITabBarController, UISplitViewController. Üst denetleyici, addChild aracılığıyla alt öğeler ekler, aralarında geçiş yapar ve düzenlerini yönetir.
UIViewController — karmaşık özel animasyonlar, kamera çalışması, haritalar, video, özel düzen ile UICollectionView için. SwiftUI View — iOS 13+ üzerinde standart arayüzler için. UIHostingController aracılığıyla birleştirme kabul edilebilir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun