Auto Layout, matematiksel kısıtlamalara (constraints) dayalı Apple'ın uyarlanabilir arayüz elemanı konumlandırma sistemidir. iOS 6 (2012) için geliştirilen Auto Layout, iPhone SE (4.7″) ile iPad Pro (12.9″) ve Dynamic Island arasında tüm cihazlarda doğru şekilde görüntülenen arayüzler oluşturmanıza olanak tanır. Apple WWDC Session 202 (2024)'ye göre, App Store'daki uygulamaların %90'ından fazlası Auto Layout veya onun bildirimsel alternatifi olan SwiftUI layout system'i kullanmaktadır. Constraints, UI öğeleri arasındaki bağımlılıkları doğrusal denklemler aracılığıyla tanımlar: view1.leading = view2.trailing + 8.
Önemli Noktalar
Auto Layout, UI öğelerini konumlandırmak için matematiksel kısıtlamalar (constraints) kullanan Apple'ın uyarlanabilir düzen sistemidir. Her öğenin sabit x, y, width, height koordinatlarına sahip olduğu çerçeve tabanlı düzenin (frame-based layout) aksine, Auto Layout öğeler arasındaki ilişkileri tanımlar: «buton ebeveynin sağ kenarından 8pt uzakta» veya «metin alanının genişliği ekran genişliğinin yarısına eşit». Mekanizma, University of Washington'da (Greg J. Badros, 1999) geliştirilen ve Apple tarafından iOS 6'da uygulanan Cassowary algoritmasına dayanır. Cassowary, önceliklerle (Required (1000), Default High (750), Default Low (250)) doğrusal eşitsizlik sistemini çözerek kısıtlama çakışmalarının yönetilmesine olanak tanır. Auto Layout üç boyut türünü destekler: intrinsic (içerik tarafından belirlenen öğenin doğal boyutu), explicit (açıkça belirlenmiş kısıtlama) ve compressible/stretchable (Content Hugging Priority ve Compression Resistance Priority aracılığıyla esnek mod).
Auto Layout'taki her UI öğesinin bir Intrinsic Content Size'ı vardır — içeriği tarafından belirlenen doğal bir boyut. UILabel için bu metin ve yazı tipine bağlıyken, UIImageView için görüntü boyutlarına bağlıdır. Content Hugging Priority (gerilmeye karşı direnç) ve Compression Resistance Priority (sıkıştırmaya karşı direnç), kullanılabilir alan değiştiğinde öğenin davranışını kontrol eder. Standart değerler: hugging için 251 ve compression resistance için 749. İki öğe alan için rekabet ederse, öncelik hangisinin önce gerileceğini belirler. Bu öncelikleri anlamak, Xcode'un hata ayıklayıcıda vurguladığı Ambiguous Layout'u (belirsiz düzen) çözmenin anahtarıdır.
Bir constraint şu denklemle tanımlanır: view1.attribute = multiplier × view2.attribute + constant. Nitelikler leading, trailing, top, bottom, centerX, centerY, width, height, firstBaseline, lastBaseline'i içerir. Multiplier oransal ilişkiler için kullanılır (view1 genişliği = 0.5 × superview genişliği). Constant sabit bir uzaklık belirler (leading = superview.leading + 16). Interface Builder araçları, Ctrl-sürükleme yoluyla görsel olarak constraint oluşturulmasına olanak tanır, ancak karmaşık düzenler NSLayoutConstraint veya VFL (Visual Format Language) aracılığıyla programlı oluşturma gerektirir; Apple, iOS 9'dan itibaren bunların NSLayoutConstraint ile değiştirilmesini önerir.
Constraint sistemi doğrusal programlama problemi olarak çözülür: Cassowary algoritması, önceliklerini dikkate alarak tüm kısıtlamaları karşılayan tüm öğelerin en uygun düzenlemesini bulur. Constraint'ler birbiriyle çelişirse, Unsatisfiable Layout oluşur — Xcode'un ayrıntılı bir çakışma açıklamasıyla günlüğe kaydettiği bir istisna. En az bir öğenin konumunu belirlemek için yeterli constraint yoksa, Ambiguous Layout oluşur — öğeler rastgele konumlarda görüntülenir. Apple minimum bir set önerir: her öğe için position (x, y) ve size (width, height) açıkça veya intrinsic content size aracılığıyla ayarlanmalıdır. Constraint'ler birinci sınıf olabilir: lider öğe (örneğin superview) ve takipçi (alt görünüm) bir hiyerarşi oluşturur.
Cassowary, doğrusal eşitsizlik sistemlerini çözmek için Sequential Quadratic Programming yöntemini kullanır. Her constraint'in 1 ile 1000 arasında bir önceliği vardır. Required (1000) zorunlu bir kısıtlamadır; karşılanamazsa uygulama NSConstraintException ile çöker. Default High (750) önerilir; Default Low (250) en az önemli olandır. Çakışma durumunda Cassowary daha düşük öncelikli kısıtlamaları gevşetir. Örneğin, iki öğe sabit genişlik gerektiriyor ancak ekran çok darsa, daha düşük öncelikli constraint gevşetilir. Xcode Debug View Hierarchy'de (Xcode 6'dan beri kullanılabilen hata ayıklama aracı) yalnızca Required constraint'lerle ilgili sorunlar vurgulanır — diğerleri hatasız işlenir.
UIStackView, iOS 9'da (2015) tanıtılan, iç içe arrangedSubviews için otomatik olarak constraint oluşturan ve yöneten bir kapsayıcıdır. UIStackView iki ekseni destekler: yatay ve dikey. Distribution ayarları alan dağılımını belirler: fill (hugging priority'ye göre oransal doldurma), fillEqually (eşit boyutlar), fillProportionally (intrinsic content size'a orantılı), equalSpacing (eşit aralık), equalCentering (merkezler arası eşit mesafe). Alignment, çapraz eksen hizalamasını tanımlar: fill, leading, center, trailing (yatay için) veya fill, top, center, bottom (dikey için). UIStackView, aralığı, taban çizgisi hizalamasını ve Dynamic Type'a uyumu otomatik olarak yönetir.
import UIKit
class StackViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let stack = UIStackView()
stack.axis = NSLayoutConstraint.Axis.vertical
stack.distribution = .fillEqually
stack.spacing = 8
stack.translatesAutoresizingMaskIntoConstraints = false
let label = UILabel()
label.text = "Auto Layout Guide"
label.font = UIFont.preferredFont(forTextStyle: .headline)
let button = UIButton(type: .system)
button.setTitle("Apply", for: .normal)
stack.addArrangedSubview(label)
stack.addArrangedSubview(button)
view.addSubview(stack)
NSLayoutConstraint.activate([
stack.centerXAnchor.constraint(equalTo: view.centerXAnchor),
stack.centerYAnchor.constraint(equalTo: view.centerYAnchor),
stack.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: 16),
stack.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -16)
])
}
}Kod, iki öğeli (UILabel ve UIButton) dikey bir UIStackView oluşturur, 8pt aralıkla eşit olarak dağıtılır (fillEqually). Stack, kenarlardan en az 16pt kenar boşluğuyla ekranın ortasına hizalanır. translatesAutoresizingMaskIntoConstraints = false, programlı olarak constraint oluştururken zorunludur — onsuz Auto Layout çalışmaz. IT Sectr'de, UIStackView iOS proje ekranlarının %80'inde uyarlanabilir formlar, ayar listeleri ve kartlar oluşturmak için kullanılır.
UIStackView'lar iç içe yerleştirilebilir: dikey bir stack içindeki yatay stack, karmaşık düzenler için standart bir desendir. Dış stack satırları yönetir, iç stack her satır içindeki sütunları yönetir. Her seviyede axis, alignment ve distribution kombinasyonu, tek bir manuel constraint olmadan neredeyse sınırsız esneklik sağlar. Apple, UIStackView'i UIKit'te birincil düzen aracı olarak önerir ve yalnızca stack'ler tarafından kapsanmayan durumlar için manuel NSLayoutConstraint'e başvurur: örtüşen görünümler, hassas piksel konumlandırma, özel bounds animasyonu.
NSLayoutConstraint, kodda bireysel kısıtlamalar oluşturmak için programlı bir API'dir. Her constraint, parametrelerle bir başlatıcı aracılığıyla oluşturulur: item, attribute, relatedBy, toItem, attribute, multiplier, constant. iOS 9'dan itibaren Apple, Anchor API'yi tanıttı — view.leadingAnchor, view.trailingAnchor, view.topAnchor, view.bottomAnchor, view.centerXAnchor, view.centerYAnchor, view.widthAnchor, view.heightAnchor özellikleri aracılığıyla daha okunabilir bir sözdizimi. Anchor API otomatik olarak relatedBy = .equal ayarlar ve Anchors'tan First Item/Second Item kullanır, böylece klasik NSLayoutConstraint'e kıyasla kodu %40 oranında azaltır.
import UIKit
class ConstraintViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let childView = UIView()
childView.backgroundColor = .systemBlue
childView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(childView)
NSLayoutConstraint.activate([
childView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 24),
childView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
childView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
childView.heightAnchor.constraint(equalToConstant: 120),
childView.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor, constant: -24)
])
}
}Kod, childView'i safeAreaLayoutGuide (top) ve ekran kenarlarından (leading/trailing) kenar boşluklarıyla konumlandırır. Bottom için lessThanOrEqualTo, görünümün alt sınırı aşmamasını sağlar. Anchor API, anchor'lar uyumsuzsa (örneğin, leadingAnchor'un rightAnchor ile karıştırılması) derleme zamanında bir istisna fırlatarak çalışma zamanı hatalarını önler. Apple, iOS 9'dan itibaren programlı Auto Layout için Anchor API'yi standart olarak önerir.
Safe Area, Dynamic Island, Notch, Status Bar, Home Indicator, yuvarlatılmış köşeler gibi sistem öğeleri tarafından kapsanmayan ekran alanıdır. iOS 11'de Apple, topLayoutGuide/bottomLayoutGuide'ı safeAreaLayoutGuide ile değiştirdi; bu, cihaz yönüne ve ekran kesintisinin varlığına otomatik olarak uyum sağlar. Layout Margins, varsayılan iç görünüm kenar boşluklarıdır (iOS'ta 16pt, iPadOS'te 20pt). UILayoutGuide için RIGHT-TO-LEFT yerelleştirmesini dikkate alarak özel directionalLayoutMargins ayarlayabilirsiniz. Auto Layout, anchor'larda safeAreaLayoutGuide kullanıldığında otomatik olarak safe area'ya saygı gösterir.
Dynamic Island (iPhone 14 Pro ve daha yenisi) ve Notch (iPhone X–13) içeren cihazlarda Safe Area, portre modunda üstte 44pt'yi (etkin durumda Dynamic Island ile 59pt) hariç tutar. Home Indicator altta 34pt ekler. Doğru uyum için, tüm üst constraint'ler safeAreaLayoutGuide.topAnchor'a bağlanmalıdır, view.topAnchor'a değil. Alt constraint'ler safeAreaLayoutGuide.bottomAnchor veya Home Indicator için kenar boşluğu olan view.bottomAnchor'a bağlanmalıdır. IT Sectr'de, tüm ekranları iPhone SE (2022), iPhone 14 Pro Max ve iPad Pro 12.9″ simülatörlerinde test ediyoruz — tüm safe area varyasyonlarını kapsayan üç cihaz.
Auto Layout ile çalışırken en sık yapılan hatalar: unutulan translatesAutoresizingMaskIntoConstraints = false, çakışan Required constraint'ler (öncelik 1000), Ambiguous Layout (konumu belirlemek için yetersiz constraint), çok satırlı UILabel için yanlış Content Hugging Priority ve leading/trailing ile left/right anchor'larının karıştırılması. Xcode 15+, Runtime Issue Navigator'da düzen sorunlarını görüntüler ve otomatik düzeltmeler sunar. Karmaşık düzenler için Debug View Hierarchy kullanın: sarı işaretçiler ambiguous layout'u, kırmızı işaretçiler unsatisfiable'ı gösterir.
| Hata | Neden | Çözüm |
|---|---|---|
| translatesAutoresizingMaskIntoConstraints = true | Auto Layout görünüm için etkinleştirilmemiş | Tüm programlı görünümler için false olarak ayarlayın |
| Unsatisfiable Layout | Required (1000) constraint çakışması | Bir önceliği Default High (750)'ye düşürün |
| Ambiguous Layout | x/y/w/h için yetersiz constraint | Eksik constraint ekleyin veya intrinsic size'ı kontrol edin |
| UILabel'de metin kesilmesi | Content Hugging Priority rakipten düşük | Hugging priority'yi 252+ yükseltin |
| LTR/RTL anchor karışımı | leadingAnchor ile rightAnchor | RTL desteği için yalnızca leading/trailing kullanın |
Sıkça Sorulan Sorular
Çerçeve tabanlı düzen, her öğe için sabit x, y, width, height koordinatları belirler. Auto Layout, matematiksel kısıtlamalar (constraints) kullanır — öğeler arasındaki ilişkiler: «label.leading = button.trailing + 8». Çerçeve tabanlı düzen ekran boyutuna uyum sağlamaz; Auto Layout, döndürme, Split View veya Dynamic Type değişikliklerinde konumları otomatik olarak yeniden hesaplar.
UIStackView doğrusal düzenler için idealdir: satırlar, sütunlar, formlar, parametre listeleri. NSLayoutConstraint, örtüşen görünümler, hassas piksel konumlandırma, özel bounds animasyonu ve alan dağılımının eşit olmadığı ve UIStackView distribution'ı tarafından kapsanmayan durumlar için gereklidir. Pratikte düzenlerin %80'i UIStackView ile çözülür, %20'si manuel constraint'lerle.
Content Hugging Priority (gerilmeye karşı direnç), bir öğenin Intrinsic Content Size'ın ötesinde boyutunun artmasına ne kadar direndiğini belirleyen bir önceliktir. Varsayılan değer 251'dir. İki öğe boş alan için rekabet ederse, daha yüksek hugging priority'ye sahip öğe boyutunu korurken diğeri gerilir. Compression Resistance Priority (varsayılan 749) sıkıştırma için benzer şekilde çalışır.
Auto Layout, constraint'ler etiketlerin intrinsic content size'ını kullanıyorsa Dynamic Type'a otomatik olarak uyum sağlar. Yazı tipi boyutu arttığında UILabel genişler, constraint'ler aracılığıyla komşu öğeleri kaydırır. distribution = fillProportionally olan UIStackView, alanı yeni intrinsic size'larla orantılı olarak yeniden dağıtır. Safe Area ve Layout Margins de erişilebilirlik ayarlarına saygı gösterir.
Unsatisfiable Layout, iki Required (priority = 1000) constraint birbiriyle çeliştiğinde oluşur: örneğin, view.leading = superview.leading + 16 ve view.trailing = superview.leading + 200 ve superview genişliği 100pt olduğunda. Cassowary algoritması bir çözüm bulamaz ve uygulama NSConstraintException ile çöker. Çözüm, çakışan constraint'lerden birinin önceliğini Default High (750)'ye düşürmektir.
Ö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