Auto Layout — sistema ng adaptive na pagpoposisyon ng mga elemento ng interface mula sa Apple, batay sa mga matematikal na hadlang (constraints). Binuo para sa iOS 6 (2012), pinapayagan ng Auto Layout na lumikha ng mga interface na wastong naipapakita sa lahat ng device — mula iPhone SE (4.7″) hanggang iPad Pro (12.9″) at Dynamic Island. Ayon sa Apple WWDC Session 202 (2024), higit sa 90% ng mga app sa App Store ay gumagamit ng Auto Layout o ang deklaratibong alternatibo nito — SwiftUI layout system. Inilalarawan ng Constraints ang mga dependency sa pagitan ng mga UI-element sa pamamagitan ng mga linear equation: view1.leading = view2.trailing + 8.
Pangunahin
Auto Layout — ay ang adaptive layout system ng Apple, na gumagamit ng matematikal na mga hadlang (constraints) para sa pagpoposisyon ng mga UI-element. Hindi tulad ng frame-based layout, kung saan ang bawat elemento ay may nakapirming coordinate x, y, width, height, inilalarawan ng Auto Layout ang mga relasyon sa pagitan ng mga elemento: «ang button ay nasa 8pt mula sa kanang gilid ng parent» o «ang lapad ng text field ay katumbas ng kalahati ng lapad ng screen». Ang mekanismo ay batay sa Cassowary algorithm, na binuo sa University of Washington (Greg J. Badros, 1999) at ipinatupad ng Apple sa iOS 6. Nilulutas ng Cassowary ang isang sistema ng linear inequalities na may mga priyoridad — Required (1000), Default High (750), Default Low (250) — na nagpapahintulot sa pamamahala ng mga conflict ng hadlang. Sinusuportahan ng Auto Layout ang tatlong uri ng laki: intrinsic (natural na laki ng elemento na tinutukoy ng nilalaman), explicit (hayagang tinukoy na constraint) at compressible/stretchable (elastic mode sa pamamagitan ng Content Hugging Priority at Compression Resistance Priority).
Ang bawat UI-element sa Auto Layout ay may Intrinsic Content Size — natural na laki na tinutukoy ng nilalaman nito. Para sa UILabel depende ito sa teksto at font, para sa UIImageView — sa mga dimensyon ng larawan. Ang Content Hugging Priority (paglaban sa pag-unat) at Compression Resistance Priority (paglaban sa pag-compress) ay namamahala sa pag-uugali ng elemento kapag nagbabago ang available na espasyo. Mga karaniwang halaga: 251 para sa hugging at 749 para sa compression resistance. Kung ang dalawang elemento ay nakikipagkumpitensya para sa espasyo, tinutukoy ng priyoridad kung alin ang unang uunat. Ang pag-unawa sa mga priyoridad na ito ay susi sa pag-aalis ng Ambiguous Layout (hindi malinaw na layout), na itinatampok ng Xcode sa debugger.
Ang constraint ay inilalarawan ng equation: view1.attribute = multiplier × view2.attribute + constant. Kasama sa mga attribute ang leading, trailing, top, bottom, centerX, centerY, width, height, firstBaseline, lastBaseline. Ang multiplier ay ginagamit para sa proporsyonal na relasyon (lapad view1 = 0.5 × lapad superview). Tinutukoy ng constant ang nakapirming distansya (leading = superview.leading + 16). Ang mga tool ng Interface Builder ay nagpapahintulot ng visual na pagtatakda ng constraints sa pamamagitan ng Ctrl-drag, ngunit ang mga kumplikadong layout ay nangangailangan ng programatikong paggawa sa pamamagitan ng NSLayoutConstraint o VFL (Visual Format Language), na inirerekomenda ng Apple na palitan ng NSLayoutConstraint simula iOS 9.
Ang sistema ng constraints ay nilulutas bilang isang linear programming problem: ang Cassowary algorithm ay hinahanap ang optimal na pagpoposisyon ng lahat ng elemento, na natutugunan ang lahat ng hadlang na isinasaalang-alang ang kanilang mga priyoridad. Kung ang constraints ay sumasalungat sa isa't isa, lumilitaw ang Unsatisfiable Layout — isang exception na nilolog ng Xcode na may detalyadong paglalarawan ng conflict. Kung ang constraints ay hindi sapat upang matukoy ang posisyon ng kahit isang elemento, lumilitaw ang Ambiguous Layout — ang mga elemento ay ipinapakita sa di-makatwirang posisyon. Inirerekomenda ng Apple ang minimal na set: para sa bawat elemento ay dapat tukuyin ang position (x, y) at size (width, height) — hayagan o sa pamamagitan ng intrinsic content size. Ang constraints ay maaaring first-class: ang nangungunang elemento (hal. superview) at ang dependent (child view) ay lumilikha ng hierarchy.
Ginagamit ng Cassowary ang pamamaraang Sequential Quadratic Programming para sa paglutas ng mga sistema ng linear inequalities. Ang bawat constraint ay may priyoridad mula 1 hanggang 1000. Required (1000) — sapilitang hadlang; kung hindi ito matupad, ang app ay nag-crash na may NSConstraintException. Default High (750) — inirerekomenda; Default Low (250) — pinakamaliit ang kahalagahan. Sa conflict, niluluwagan ng Cassowary ang mga hadlang na may mas mababang priyoridad. Halimbawa, kung dalawang elemento ay nangangailangan ng nakapirming lapad at ang screen ay masyadong makitid, ang constraint na may mas mababang priyoridad ay niluluwagan. Sa Xcode Debug View Hierarchy (debug tool na available simula Xcode 6) itinatampok lamang ang mga problema sa Required constraints — ang iba ay pinoproseso nang walang error.
UIStackView — lalagyan na ipinakilala sa iOS 9 (2015), na awtomatikong lumilikha at namamahala ng constraints para sa nested arrangedSubviews. Sinusuportahan ng UIStackView ang dalawang axis: horizontal (pahalang na layout) at vertical (patayo). Tinutukoy ng mga setting ng distribution ang pamamahagi ng espasyo: fill (pagpuno proporsyonal sa hugging priority), fillEqually (pantay na laki), fillProportionally (proporsyonal sa intrinsic content size), equalSpacing (pantay na pagitan), equalCentering (pantay na distansya sa pagitan ng mga center). Tinutukoy ng alignment ang pagkakapantay-pantay sa kabila ng axis: fill, leading, center, trailing (para sa horizontal) o fill, top, center, bottom (para sa vertical). Awtomatikong namamahala ang UIStackView ng spacing, baseline alignment at pag-adapt sa Dynamic Type.
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 = "Gabay sa Auto Layout"
label.font = UIFont.preferredFont(forTextStyle: .headline)
let button = UIButton(type: .system)
button.setTitle("Ilapat", 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)
])
}
}Ang code ay lumilikha ng vertical UIStackView na may dalawang elemento (UILabel at UIButton), pantay na ipinamahagi (fillEqually) na may pagitan na 8pt. Ang stack ay naka-center sa screen na may mga margin mula sa mga gilid ng hindi bababa sa 16pt. translatesAutoresizingMaskIntoConstraints = false ay sapilitan sa programatikong paggawa ng constraints — kung wala ito, hindi gagana ang Auto Layout. Sa IT Sectr, ang UIStackView ay ginagamit sa 80% ng mga screen ng iOS project para sa pagbuo ng mga adaptive form, listahan ng setting at card.
Ang UIStackView ay maaaring nested: pahalang na stack sa loob ng patayo — karaniwang pattern para sa kumplikadong layout. Ang panlabas na stack ay namamahala ng mga row, ang panloob — mga column sa loob ng row. Ang kumbinasyon ng axis, alignment at distribution sa bawat antas ay nagbibigay ng halos walang limitasyong flexibility nang walang kahit isang manual constraint. Inirerekomenda ng Apple ang paggamit ng UIStackView bilang pangunahing layout tool sa UIKit, gamit ang manual NSLayoutConstraint lamang para sa mga kaso na hindi sakop ng stack: magkakapatong na view, pixel-precise positioning, custom bounds animation.
NSLayoutConstraint — programming API para sa paggawa ng indibidwal na mga hadlang sa code. Ang bawat constraint ay ginagawa sa pamamagitan ng initializer na may mga parameter: item, attribute, relatedBy, toItem, attribute, multiplier, constant. Mula iOS 9 ipinakilala ng Apple ang Anchor API — mas nababasang syntax sa pamamagitan ng mga property na view.leadingAnchor, view.trailingAnchor, view.topAnchor, view.bottomAnchor, view.centerXAnchor, view.centerYAnchor, view.widthAnchor, view.heightAnchor. Awtomatikong itinatakda ng Anchor API ang relatedBy = .equal at ginagamit ang First Item/Second Item mula sa Anchor, binabawasan ang code ng 40% kumpara sa klasikong NSLayoutConstraint.
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)
])
}
}Ang code ay nagpoposisyon ng childView na may mga margin mula sa safeAreaLayoutGuide (top) at mga gilid ng screen (leading/trailing). Ang lessThanOrEqualTo para sa bottom ay tinitiyak na ang view ay hindi lalampas sa ibabang hangganan. Ang Anchor API ay nagtatapon ng exception sa compilation stage kung ang mga anchor ay hindi compatible (hal. leadingAnchor ay hinaluan ng rightAnchor), na pumipigil sa runtime error. Inirerekomenda ng Apple ang Anchor API bilang pamantayan para sa programatikong Auto Layout simula iOS 9.
Safe Area — ang lugar ng screen na hindi natatakpan ng mga system element: Dynamic Island, Notch, Status Bar, Home Indicator, bilugan na sulok. Sa iOS 11 pinalitan ng Apple ang topLayoutGuide/bottomLayoutGuide ng safeAreaLayoutGuide, na awtomatikong uma-adapt sa oryentasyon ng device at pagkakaroon ng screen cutout. Layout Margins — default na internal margin ng view (16pt sa iOS, 20pt sa iPadOS). Para sa UILayoutGuide ay maaaring itakda ang custom na directionalLayoutMargins na isinasaalang-alang ang RIGHT-TO-LEFT localization. Awtomatikong isinasaalang-alang ng Auto Layout ang safe area kapag ginagamit ang safeAreaLayoutGuide sa mga anchor.
Sa mga device na may Dynamic Island (iPhone 14 Pro at mas bago) at Notch (iPhone X–13) ang Safe Area ay hindi kasama ang 44pt mula sa itaas sa portrait (59pt na may Dynamic Island sa aktibong estado). Ang Home Indicator ay nagdaragdag ng 34pt mula sa ibaba. Para sa tamang pag-adapt, ang lahat ng top-constraints ay dapat nakatali sa safeAreaLayoutGuide.topAnchor, hindi sa view.topAnchor. Bottom-constraints — sa safeAreaLayoutGuide.bottomAnchor o view.bottomAnchor na may reserba para sa Home Indicator. Sa IT Sectr, sinusubukan namin ang lahat ng screen sa mga simulator ng iPhone SE (2022), iPhone 14 Pro Max at iPad Pro 12.9″ — tatlong device na sumasaklaw sa lahat ng variant ng safe area.
Ang pinakakaraniwang pagkakamali sa pagtatrabaho sa Auto Layout: nakalimutang translatesAutoresizingMaskIntoConstraints = false, nagkakasalungat na Required constraints (priyoridad 1000), Ambiguous Layout (hindi sapat na constraints upang matukoy ang posisyon), maling Content Hugging Priority para sa UILabel na may multi-line na teksto at paghahalo ng leading/trailing sa left/right anchors. Ang Xcode 15+ ay nagpapakita ng mga layout issue sa Runtime Issue Navigator at nag-aalok ng awtomatikong pagwawasto. Para sa kumplikadong layout gamitin ang Debug View Hierarchy: ang dilaw na label ay nagpapahiwatig ng ambiguous layout, pula — unsatisfiable.
| Pagkakamali | Dahilan | Solusyon |
|---|---|---|
| translatesAutoresizingMaskIntoConstraints = true | Hindi aktibo ang Auto Layout para sa view | Itakda ang false para sa lahat ng programatikong view |
| Unsatisfiable Layout | Conflict ng Required (1000) constraints | Ibaba ang priyoridad ng isa sa Default High (750) |
| Ambiguous Layout | Hindi sapat na constraints para sa x/y/w/h | Magdagdag ng nawawalang constraint o suriin ang intrinsic size |
| Pagputol ng teksto sa UILabel | Mas mababa ang Content Hugging Priority kaysa sa kalaban | Taasan ang hugging priority sa 252+ |
| Paghahalo ng LTR/RTL anchor | leadingAnchor sa rightAnchor | Gamitin lamang ang leading/trailing para sa suporta ng RTL |
Mga Madalas Itanong
Frame-based layout ay nagtatakda ng nakapirming coordinate x, y, width, height para sa bawat elemento. Ang Auto Layout ay gumagamit ng matematikal na mga hadlang (constraints) — mga relasyon sa pagitan ng mga elemento: «label.leading = button.trailing + 8». Ang frame-based layout ay hindi uma-adapt sa laki ng screen; ang Auto Layout ay awtomatikong nagre-recalculate ng mga posisyon sa pag-ikot, Split View o pagbabago ng Dynamic Type.
UIStackView ay optimal para sa mga linear na layout: mga row, column, form, listahan ng parameter. Ang NSLayoutConstraint ay kinakailangan para sa magkakapatong na view, pixel-precise positioning, custom bounds animation at mga kaso kung saan ang distribusyon ng espasyo ay hindi pantay at hindi sakop ng distribution ng UIStackView. Sa praktika, 80% ng mga layout ay nilulutas ng UIStackView, 20% — ng manual constraints.
Content Hugging Priority (paglaban sa pag-unat) — priyoridad na tumutukoy kung gaano kalaki ang paglaban ng elemento sa pagtaas ng laki nito lampas sa Intrinsic Content Size. Default na halaga — 251. Kung ang dalawang elemento ay nakikipagkumpitensya para sa libreng espasyo, ang elemento na may mas mataas na hugging priority ay mananatili sa laki nito, at ang isa ay uunat. Ang Compression Resistance Priority (default 749) ay gumagana nang kahalintulad para sa compression.
Awtomatikong uma-adapt ang Auto Layout sa Dynamic Type kung ang constraints ay gumagamit ng intrinsic content size ng mga label. Kapag tumaas ang laki ng font, lumalawak ang UILabel, inililipat ang mga katabing elemento sa pamamagitan ng constraints. Ang UIStackView na may distribution = fillProportionally ay muling namamahagi ng espasyo nang proporsyonal sa mga bagong intrinsic size. Ang Safe Area at Layout Margins ay isinasaalang-alang din ang mga setting ng accessibility.
Unsatisfiable Layout ay nangyayari kapag ang dalawang Required (priority = 1000) constraints ay sumasalungat sa isa't isa: halimbawa view.leading = superview.leading + 16 at view.trailing = superview.leading + 200 na may superview na lapad na 100pt. Ang Cassowary algorithm ay hindi makahanap ng solusyon at ang app ay nag-crash na may NSConstraintException. Solusyon — ibaba ang priyoridad ng isa sa mga nagkakasalungat na constraints sa Default High (750).
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din