Auto Layout: шта је то, адаптивни распоред интерфејса iOS

Аутор: IT Sectr Објављено: 2026-02-21 Време читања: 9 мин

Auto Layout — систем адаптивног позиционирања елемената интерфејса од Apple-а, заснован на математичким ограничењима (constraints). Развијен за iOS 6 (2012), Auto Layout омогућава креирање интерфејса који се коректно приказују на свим уређајима — од iPhone SE (4.7″) до iPad Pro (12.9″) и Dynamic Island. Према Apple WWDC Session 202 (2024), више од 90% апликација у App Store користи Auto Layout или његову декларативну алтернативу — SwiftUI layout system. Constraints описују зависности између UI елемената кроз линеарне једначине: view1.leading = view2.trailing + 8.

Главно

  • Auto Layout — систем адаптивног распореда Apple-а кроз математичка ограничења (constraints) за све величине екрана.
  • Constraints — линеарне једначине облика view1.attribute = multiplier × view2.attribute + constant, решаване Cassowary алгоритмом.
  • UIStackView — контејнер који аутоматски управља constraints за угњеждене view (horizontal/vertical, alignment, distribution).
  • NSLayoutConstraint — програмски API за креирање ограничења у коду са активацијом кроз isActive = true.
  • Safe Area и Layout Margins — уграђене маргине Auto Layout-а које искључују преклапање са Dynamic Island, Notch и Home Indicator.

Шта је Auto Layout?

Auto Layout — је систем адаптивног распореда Apple-а, који користи математичка ограничења (constraints) за позиционирање UI елемената. За разлику од оквирног распореда (frame-based layout), где сваки елемент има фиксне координате x, y, width, height, Auto Layout описује односе између елемената: «дугме се налази 8pt од десне ивице родитеља» или «ширина текстуалног поља је једнака половини ширине екрана». Механизам се заснива на Cassowary алгоритму, развијеном на University of Washington (Greg J. Badros, 1999) и имплементираном од стране Apple-а у iOS 6. Cassowary решава систем линеарних неједнакости са приоритетима — Required (1000), Default High (750), Default Low (250) — што омогућава управљање конфликтима ограничења. Auto Layout подржава три типа величина: intrinsic (природна величина елемента одређена садржајем), explicit (експлицитно задато constraint) и compressible/stretchable (еластични режим кроз Content Hugging Priority и Compression Resistance Priority).

Intrinsic Content Size и приоритети

Сваки UI елемент у Auto Layout-у има Intrinsic Content Size — природну величину одређену својим садржајем. За UILabel то зависи од текста и фонта, за UIImageView — од димензија слике. Content Hugging Priority (отпор истезању) и Compression Resistance Priority (отпор сабијању) управљају понашањем елемента при промени расположивог простора. Стандардне вредности: 251 за hugging и 749 за compression resistance. Ако се два елемента такмиче за простор, приоритет одређује који ће се први растегнути. Разумевање ових приоритета је кључ за уклањање Ambiguous Layout (нејасног распореда), који Xcode истиче у дебагеру.

Анатомија Constraint-а

Constraint се описује једначином: view1.attribute = multiplier × view2.attribute + constant. Атрибути укључују leading, trailing, top, bottom, centerX, centerY, width, height, firstBaseline, lastBaseline. Multiplier се користи за пропорционалне односе (ширина view1 = 0.5 × ширина superview). Constant задаје фиксни размак (leading = superview.leading + 16). Алати Interface Builder-а омогућавају визуелно задавање constraints кроз Ctrl-превлачење, али сложени распореди захтевају програмско креирање кроз NSLayoutConstraint или VFL (Visual Format Language), који Apple препоручује да се замени са NSLayoutConstraint од iOS 9.

Како Constraints раде у iOS

Систем constraints се решава као задатак линеарног програмирања: Cassowary алгоритам проналази оптимални положај свих елемената, задовољавајући сва ограничења узимајући у обзир њихове приоритете. Ако су constraints у међусобној супротности, настаје Unsatisfiable Layout — изузетак који Xcode логира са детаљним описом конфликта. Ако constraints нису довољни за одређивање положаја макар једног елемента, настаје Ambiguous Layout — елементи се приказују на произвољном положају. Apple препоручује минимални скуп: за сваки елемент морају бити одређени position (x, y) и size (width, height) — експлицитно или кроз intrinsic content size. Constraints могу бити first-class: водећи елемент (нпр. superview) и зависни (приказујући view) стварају хијерархију.

Cassowary алгоритам и приоритети

Cassowary користи метод Sequential Quadratic Programming за решавање система линеарних неједнакости. Сваки constraint има приоритет од 1 до 1000. Required (1000) — обавезно ограничење; ако се не може испунити, апликација пада са NSConstraintException. Default High (750) — препоручујуће; Default Low (250) — најмање важно. При конфликту Cassowary опушта ограничења са нижим приоритетом. На пример, ако два елемента захтевају фиксну ширину, а екран је преузак, опушта се constraint са нижим приоритетом. У Xcode Debug View Hierarchy (алат за отклањање грешака доступан од Xcode 6) истиче само проблеме са Required constraints — остали се обрађују без грешке.

UIStackView: аутоматско управљање Constraints

UIStackView — контејнер представљен у iOS 9 (2015), који аутоматски креира и управља constraints за угњеждене arrangedSubviews. UIStackView подржава две осе: horizontal (хоризонтални распоред) и vertical (вертикални). Подешавања distribution одређују расподелу простора: fill (пуњење пропорционално hugging priority), fillEqually (једнаке величине), fillProportionally (пропорционално intrinsic content size), equalSpacing (једнаки размаци), equalCentering (једнаке удаљености између центара). Alignment задаје поравнање попречно на осу: fill, leading, center, trailing (за horizontal) или fill, top, center, bottom (за vertical). UIStackView аутоматски управља spacing, baseline alignment и адаптацијом на Dynamic Type.

swift
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 водич"
        label.font = UIFont.preferredFont(forTextStyle: .headline)
        
        let button = UIButton(type: .system)
        button.setTitle("Примени", 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)
        ])
    }
}

Код креира вертикални UIStackView са два елемента (UILabel и UIButton), равномерно распоређена (fillEqually) са размаком од 8pt. Stack је центриран на екрану са маргинама од ивица од најмање 16pt. translatesAutoresizingMaskIntoConstraints = false је обавезан при програмском креирању constraints — без њега Auto Layout не ради. У IT Sectr-у, UIStackView се користи у 80% екрана iOS пројеката за изградњу адаптивних форми, листа подешавања и картица.

Угњеждени Stack View-ови

UIStackView-ови могу бити угњеждени: хоризонтални стек унутар вертикалног — стандардни образац за сложене распореде. Спољашњи стек управља редовима, унутрашњи — колонама унутар реда. Комбинација axis, alignment и distribution на сваком нивоу даје практично неограничену флексибилност без иједног ручног constraint-а. Apple препоручује коришћење UIStackView-а као главног алата за распоред у UIKit-у, прибегавајући ручним NSLayoutConstraint само за случајеве које стек не покрива: преклапајући view, прецизно позиционирање по пикселима, прилагођена анимација bounds.

NSLayoutConstraint: програмско креирање ограничења

NSLayoutConstraint — програмски API за креирање појединачних ограничења у коду. Сваки constraint се креира кроз иницијализатор са параметрима: item, attribute, relatedBy, toItem, attribute, multiplier, constant. Од iOS 9 Apple је представио Anchor API — читљивију синтаксу кроз својства view.leadingAnchor, view.trailingAnchor, view.topAnchor, view.bottomAnchor, view.centerXAnchor, view.centerYAnchor, view.widthAnchor, view.heightAnchor. Anchor API аутоматски поставља relatedBy = .equal и користи First Item/Second Item из Anchor-а, смањујући код за 40% у поређењу са класичним NSLayoutConstraint.

swift
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)
        ])
    }
}

Код позиционира childView са маргинама од safeAreaLayoutGuide (top) и ивица екрана (leading/trailing). lessThanOrEqualTo за bottom гарантује да view неће изаћи изван доње границе. Anchor API баца изузетак у фази компилације ако су anchor-и некомпатибилни (нпр. leadingAnchor се меша са rightAnchor), што спречава runtime грешке. Apple препоручује Anchor API као стандард за програмски Auto Layout од iOS 9.

Safe Area и Layout Margins у Auto Layout

Safe Area — област екрана коју не прекривају системски елементи: Dynamic Island, Notch, Status Bar, Home Indicator, заобљени углови. У iOS 11 Apple је заменио topLayoutGuide/bottomLayoutGuide са safeAreaLayoutGuide, који се аутоматски прилагођава оријентацији уређаја и присуству изреза екрана. Layout Margins — унутрашње маргине view-а подразумевано (16pt на iOS, 20pt на iPadOS). За UILayoutGuide се могу подесити прилагођени directionalLayoutMargins узимајући у обзир RIGHT-TO-LEFT локализацију. Auto Layout аутоматски узима у обзир safe area при коришћењу safeAreaLayoutGuide у anchor-има.

Адаптација на Dynamic Island и Notch

На уређајима са Dynamic Island (iPhone 14 Pro и новији) и Notch (iPhone X–13) Safe Area искључује 44pt одозго у портрету (59pt са Dynamic Island у активном стању). Home Indicator додаје 34pt одоздо. За коректну адаптацију, сви top-constraints морају бити везани за safeAreaLayoutGuide.topAnchor, а не за view.topAnchor. Bottom-constraints — за safeAreaLayoutGuide.bottomAnchor или view.bottomAnchor са резервом за Home Indicator. У IT Sectr-у тестирамо све екране на симулаторима iPhone SE (2022), iPhone 14 Pro Max и iPad Pro 12.9″ — три уређаја која покривају све варијанте safe area.

Типичне грешке Auto Layout-а

Најчешће грешке при раду са Auto Layout-ом: заборављено translatesAutoresizingMaskIntoConstraints = false, конфликтни Required constraints (приоритет 1000), Ambiguous Layout (недовољно constraints за одређивање положаја), нетачан Content Hugging Priority за UILabel са вишелинијским текстом и мешање leading/trailing са left/right anchors. Xcode 15+ приказује проблеме распореда у Runtime Issue Navigator-у и нуди аутоматске исправке. За сложене распореде користите Debug View Hierarchy: жуте ознаке указују на ambiguous layout, црвене — на unsatisfiable.

ГрешкаУзрокРешење
translatesAutoresizingMaskIntoConstraints = trueAuto Layout није активиран за viewПоставите false за све програмске view
Unsatisfiable LayoutКонфликт Required (1000) constraintsСмањите приоритет једног на Default High (750)
Ambiguous LayoutНедовољно constraints за x/y/w/hДодајте недостајући constraint или проверите intrinsic size
Скраћивање текста у UILabelContent Hugging Priority нижи од конкурентаПовећајте hugging priority на 252+
Мешање LTR/RTL anchor-аleadingAnchor са rightAnchorКористите само leading/trailing за подршку RTL

Често постављана питања

Чим се Auto Layout разликује од оквирног распореда?

Оквирни распоред поставља фиксне координате x, y, width, height за сваки елемент. Auto Layout користи математичка ограничења (constraints) — односе између елемената: «label.leading = button.trailing + 8». Оквирни распоред се не прилагођава величини екрана; Auto Layout аутоматски прерачунава позиције при ротацији, Split View или промени Dynamic Type.

Када треба користити UIStackView уместо NSLayoutConstraint?

UIStackView је оптималан за линеарне распореде: редови, колоне, форме, листе параметара. NSLayoutConstraint је неопходан за преклапајуће view, прецизно позиционирање по пикселима, прилагођену анимацију bounds и случајеве када је расподела простора неравномерна и није покривена distribution UIStackView-а. У пракси 80% распореда се решава UIStackView-ом, 20% — ручним constraints.

Шта је Content Hugging Priority у Auto Layout-у?

Content Hugging Priority (отпор истезању) — приоритет који одређује колико се елемент опире повећању своје величине изнад Intrinsic Content Size. Подразумевана вредност — 251. Ако се два елемента такмиче за слободан простор, елемент са вишим hugging priority остаје своје величине, а други се растеже. Compression Resistance Priority (подразумевано 749) ради аналогно за сабијање.

Како Auto Layout ради са Dynamic Type?

Auto Layout се аутоматски прилагођава Dynamic Type ако constraints користе intrinsic content size ознака. При повећању величине фонта, UILabel се шири, померајући суседне елементе кроз constraints. UIStackView са distribution = fillProportionally прерасподељује простор пропорционално новим intrinsic size. Safe Area и Layout Margins такође узимају у обзир accessibility подешавања.

Зашто настаје Unsatisfiable Layout?

Unsatisfiable Layout настаје када су два Required (priority = 1000) constraints у међусобној супротности: на пример, view.leading = superview.leading + 16 и view.trailing = superview.leading + 200 при superview ширине 100pt. Cassowary алгоритам не може да пронађе решење и апликација пада са NSConstraintException. Решење — смањите приоритет једног од конфликтних constraints на Default High (750).

Закључак

  • Auto Layout — систем адаптивног распореда Apple-а заснован на Cassowary алгоритму који решава систем линеарних ограничења са приоритетима.
  • Constraints — једначине облика view1.attribute = multiplier × view2.attribute + constant са приоритетима од 1 до 1000 (Required).
  • UIStackView — контејнер који аутоматски управља constraints за arrangedSubviews са подршком за осе, distribution и alignment.
  • NSLayoutConstraint са Anchor API — програмски стандард од iOS 9, смањује код за 40% у поређењу са класичним API.
  • Safe Area — област без Dynamic Island, Notch, Home Indicator; обавезна за везивање top/bottom constraints.
  • Типичне грешке — заборављено translatesAutoresizingMaskIntoConstraints, конфликт Required, Ambiguous Layout, мешање LTR/RTL anchor-а.
  • Intrinsic Content Size и приоритети (hugging 251, compression 749) управљају понашањем елемената при промени расположивог простора.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође