Auto Layout: cos'è, layout adattivo delle interfacce iOS

Autore: IT Sectr Pubblicato: 2026-02-21 Tempo di lettura: 9 min

Auto Layout è il sistema di posizionamento adattivo degli elementi dell'interfaccia di Apple, basato su vincoli matematici (constraints). Sviluppato per iOS 6 (2012), Auto Layout consente di creare interfacce che vengono visualizzate correttamente su tutti i dispositivi — da iPhone SE (4.7″) a iPad Pro (12.9″) e Dynamic Island. Secondo Apple WWDC Session 202 (2024), oltre il 90% delle app nell'App Store utilizza Auto Layout o la sua alternativa dichiarativa — SwiftUI layout system. I Constraints descrivono le dipendenze tra elementi UI tramite equazioni lineari: view1.leading = view2.trailing + 8.

Punti chiave

  • Auto Layout è il sistema di layout adattivo di Apple tramite vincoli matematici (constraints) per tutte le dimensioni dello schermo.
  • Constraints sono equazioni lineari della forma view1.attribute = multiplier × view2.attribute + constant, risolte dall'algoritmo Cassowary.
  • UIStackView è un contenitore che gestisce automaticamente i constraints per le viste annidate (horizontal/vertical, alignment, distribution).
  • NSLayoutConstraint è un'API programmatica per creare vincoli nel codice con attivazione tramite isActive = true.
  • Safe Area e Layout Margins sono margini integrati di Auto Layout che impediscono l'intersezione con Dynamic Island, Notch e Home Indicator.

Cos'è Auto Layout?

Auto Layout è il sistema di layout adattivo di Apple che utilizza vincoli matematici (constraints) per posizionare gli elementi UI. A differenza del layout basato su frame (frame-based layout), dove ogni elemento ha coordinate fisse x, y, width, height, Auto Layout descrive relazioni tra elementi: «il pulsante è a 8pt dal bordo destro del genitore» o «la larghezza del campo di testo è uguale alla metà della larghezza dello schermo». Il meccanismo si basa sull'algoritmo Cassowary, sviluppato presso l'University of Washington (Greg J. Badros, 1999) e implementato da Apple in iOS 6. Cassowary risolve un sistema di disuguaglianze lineari con priorità — Required (1000), Default High (750), Default Low (250) — consentendo la gestione dei conflitti di vincoli. Auto Layout supporta tre tipi di dimensione: intrinsic (dimensione naturale dell'elemento determinata dal contenuto), explicit (vincolo esplicitamente impostato) e compressible/stretchable (modalità elastica tramite Content Hugging Priority e Compression Resistance Priority).

Intrinsic Content Size e Priorità

Ogni elemento UI in Auto Layout ha un Intrinsic Content Size — una dimensione naturale determinata dal suo contenuto. Per UILabel questo dipende dal testo e dal font, per UIImageView — dalle dimensioni dell'immagine. Content Hugging Priority (resistenza all'allungamento) e Compression Resistance Priority (resistenza alla compressione) controllano il comportamento dell'elemento quando lo spazio disponibile cambia. Valori standard: 251 per hugging e 749 per compression resistance. Se due elementi competono per lo spazio, la priorità determina quale si allunga per primo. Comprendere queste priorità è la chiave per risolvere Ambiguous Layout (layout ambiguo), che Xcode evidenzia nel debugger.

Anatomia di un Constraint

Un constraint è descritto dall'equazione: view1.attribute = multiplier × view2.attribute + constant. Gli attributi includono leading, trailing, top, bottom, centerX, centerY, width, height, firstBaseline, lastBaseline. Multiplier è usato per relazioni proporzionali (larghezza di view1 = 0.5 × larghezza di superview). Constant imposta un offset fisso (leading = superview.leading + 16). Gli strumenti di Interface Builder consentono di creare constraint visivamente tramite Ctrl-transcinamento, ma layout complessi richiedono la creazione programmatica tramite NSLayoutConstraint o VFL (Visual Format Language), che Apple raccomanda di sostituire con NSLayoutConstraint da iOS 9.

Come funzionano i Constraints in iOS

Il sistema di constraint viene risolto come un problema di programmazione lineare: l'algoritmo Cassowary trova la disposizione ottimale di tutti gli elementi che soddisfa tutti i vincoli considerando le loro priorità. Se i constraint si contraddicono, si verifica un Unsatisfiable Layout — un'eccezione che Xcode registra con una descrizione dettagliata del conflitto. Se non ci sono constraint sufficienti per determinare la posizione di almeno un elemento, si verifica Ambiguous Layout — gli elementi vengono visualizzati in posizioni arbitrarie. Apple raccomanda un insieme minimo: per ogni elemento, position (x, y) e size (width, height) devono essere impostati — esplicitamente o tramite intrinsic content size. I constraint possono essere di prima classe: l'elemento leader (ad esempio, superview) e quello seguace (vista figlia) creano una gerarchia.

Algoritmo Cassowary e priorità

Cassowary utilizza il metodo Sequential Quadratic Programming per risolvere sistemi di disuguaglianze lineari. Ogni constraint ha una priorità da 1 a 1000. Required (1000) è un vincolo obbligatorio; se non può essere soddisfatto, l'app si blocca con NSConstraintException. Default High (750) è raccomandato; Default Low (250) è il meno importante. In caso di conflitto, Cassowary rilassa i vincoli con priorità inferiore. Ad esempio, se due elementi richiedono una larghezza fissa ma lo schermo è troppo stretto, viene rilassato il constraint con priorità inferiore. In Xcode Debug View Hierarchy (strumento di debug disponibile da Xcode 6) vengono evidenziati solo i problemi con i constraint Required — gli altri vengono gestiti senza errore.

UIStackView: gestione automatica dei Constraints

UIStackView è un contenitore introdotto in iOS 9 (2015) che crea e gestisce automaticamente i constraint per gli arrangedSubviews annidati. UIStackView supporta due assi: orizzontale e verticale. Le impostazioni di distribution determinano la distribuzione dello spazio: fill (riempimento proporzionale in base all'hugging priority), fillEqually (dimensioni uguali), fillProportionally (proporzionale all'intrinsic content size), equalSpacing (spaziatura uguale), equalCentering (distanze uguali tra i centri). Alignment definisce l'allineamento trasversale: fill, leading, center, trailing (per orizzontale) o fill, top, center, bottom (per verticale). UIStackView gestisce automaticamente la spaziatura, l'allineamento della linea di base e l'adattamento al 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 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)
        ])
    }
}

Il codice crea un UIStackView verticale con due elementi (UILabel e UIButton), distribuiti uniformemente (fillEqually) con una spaziatura di 8pt. Lo stack è centrato sullo schermo con margini di almeno 16pt dai bordi. translatesAutoresizingMaskIntoConstraints = false è obbligatorio quando si creano constraint programmaticamente — senza di esso, Auto Layout non funziona. In IT Sectr, UIStackView viene utilizzato nell'80% degli schermi dei progetti iOS per costruire moduli adattivi, elenchi di impostazioni e schede.

Stack View annidati

Gli UIStackView possono essere annidati: uno stack orizzontale dentro uno verticale è uno schema standard per layout complessi. Lo stack esterno gestisce le righe, lo stack interno gestisce le colonne all'interno di ogni riga. La combinazione di axis, alignment e distribution a ogni livello offre una flessibilità praticamente illimitata senza un singolo constraint manuale. Apple raccomanda UIStackView come strumento di layout principale in UIKit, ricorrendo a NSLayoutConstraint manuale solo per i casi non coperti dagli stack: viste sovrapposte, posizionamento preciso dei pixel, animazione personalizzata dei bounds.

NSLayoutConstraint: creazione programmatica di vincoli

NSLayoutConstraint è un'API programmatica per creare vincoli individuali nel codice. Ogni constraint viene creato tramite un inizializzatore con parametri: item, attribute, relatedBy, toItem, attribute, multiplier, constant. Da iOS 9, Apple ha introdotto l'Anchor API — una sintassi più leggibile tramite le proprietà view.leadingAnchor, view.trailingAnchor, view.topAnchor, view.bottomAnchor, view.centerXAnchor, view.centerYAnchor, view.widthAnchor, view.heightAnchor. L'Anchor API imposta automaticamente relatedBy = .equal e utilizza First Item/Second Item dagli Anchors, riducendo il codice del 40% rispetto al NSLayoutConstraint classico.

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

Il codice posiziona childView con margini da safeAreaLayoutGuide (top) e dai bordi dello schermo (leading/trailing). lessThanOrEqualTo per bottom garantisce che la vista non superi il limite inferiore. L'Anchor API lancia un'eccezione in fase di compilazione se gli anchor sono incompatibili (ad esempio, leadingAnchor mescolato con rightAnchor), prevenendo errori a runtime. Apple raccomanda l'Anchor API come standard per Auto Layout programmatico da iOS 9.

Safe Area e Layout Margins in Auto Layout

Safe Area è l'area dello schermo non coperta dagli elementi di sistema: Dynamic Island, Notch, Status Bar, Home Indicator, angoli arrotondati. In iOS 11, Apple ha sostituito topLayoutGuide/bottomLayoutGuide con safeAreaLayoutGuide, che si adatta automaticamente all'orientamento del dispositivo e alla presenza del ritaglio dello schermo. I Layout Margins sono i margini interni predefiniti della vista (16pt su iOS, 20pt su iPadOS). Per UILayoutGuide è possibile impostare directionalLayoutMargins personalizzati considerando la localizzazione RIGHT-TO-LEFT. Auto Layout rispetta automaticamente la safe area quando si utilizza safeAreaLayoutGuide negli anchor.

Adattamento per Dynamic Island e Notch

Sui dispositivi con Dynamic Island (iPhone 14 Pro e successivi) e Notch (iPhone X–13), Safe Area esclude 44pt in alto in modalità ritratto (59pt con Dynamic Island in stato attivo). Home Indicator aggiunge 34pt in basso. Per un corretto adattamento, tutti i constraint superiori devono essere collegati a safeAreaLayoutGuide.topAnchor, non a view.topAnchor. I constraint inferiori devono essere collegati a safeAreaLayoutGuide.bottomAnchor o view.bottomAnchor con un margine per Home Indicator. In IT Sectr, testiamo tutti gli schermi sui simulatori iPhone SE (2022), iPhone 14 Pro Max e iPad Pro 12.9″ — tre dispositivi che coprono tutte le variazioni di safe area.

Errori comuni di Auto Layout

Gli errori più frequenti quando si lavora con Auto Layout: dimenticare translatesAutoresizingMaskIntoConstraints = false, constraint Required in conflitto (priorità 1000), Ambiguous Layout (constraint insufficienti per determinare la posizione), Content Hugging Priority errato per UILabel multilinea e mescolanza di anchor leading/trailing con left/right. Xcode 15+ mostra i problemi di layout nel Runtime Issue Navigator e offre correzioni automatiche. Per layout complessi, utilizzare Debug View Hierarchy: i marcatori gialli indicano ambiguous layout, quelli rossi indicano unsatisfiable.

ErroreCausaSoluzione
translatesAutoresizingMaskIntoConstraints = trueAuto Layout non attivato per la vistaImpostare false per tutte le viste programmatiche
Unsatisfiable LayoutConflitto di constraint Required (1000)Ridurre una priorità a Default High (750)
Ambiguous LayoutConstraint insufficienti per x/y/w/hAggiungere constraint mancante o verificare intrinsic size
Troncamento del testo in UILabelContent Hugging Priority inferiore al concorrenteAumentare hugging priority a 252+
Mescolanza di anchor LTR/RTLleadingAnchor con rightAnchorUtilizzare solo leading/trailing per supporto RTL

Domande frequenti

In cosa differisce Auto Layout dal layout basato su frame?

Il layout basato su frame imposta coordinate fisse x, y, width, height per ogni elemento. Auto Layout utilizza vincoli matematici (constraints) — relazioni tra elementi: «label.leading = button.trailing + 8». Il layout basato su frame non si adatta alla dimensione dello schermo; Auto Layout ricalcola automaticamente le posizioni in caso di rotazione, Split View o modifica del Dynamic Type.

Quando dovrei usare UIStackView invece di NSLayoutConstraint?

UIStackView è ottimale per layout lineari: righe, colonne, moduli, elenchi di parametri. NSLayoutConstraint è necessario per viste sovrapposte, posizionamento preciso dei pixel, animazione personalizzata dei bounds e casi in cui la distribuzione dello spazio non è uniforme e non è coperta dalla distribution di UIStackView. In pratica, l'80% dei layout viene risolto con UIStackView, il 20% con constraint manuali.

Cos'è Content Hugging Priority in Auto Layout?

Content Hugging Priority (resistenza all'allungamento) è una priorità che determina quanto un elemento resiste all'aumento delle sue dimensioni oltre l'Intrinsic Content Size. Il valore predefinito è 251. Se due elementi competono per lo spazio libero, l'elemento con hugging priority più alta mantiene le sue dimensioni mentre il secondo si allunga. Compression Resistance Priority (749 predefinito) funziona in modo simile per la compressione.

Come funziona Auto Layout con Dynamic Type?

Auto Layout si adatta automaticamente a Dynamic Type se i constraint utilizzano l'intrinsic content size delle etichette. Quando la dimensione del carattere aumenta, UILabel si espande, spostando gli elementi vicini attraverso i constraint. UIStackView con distribution = fillProportionally ridistribuisce lo spazio proporzionalmente ai nuovi intrinsic size. Safe Area e Layout Margins rispettano anche le impostazioni di accessibilità.

Perché si verifica Unsatisfiable Layout?

Unsatisfiable Layout si verifica quando due constraint Required (priority = 1000) si contraddicono: ad esempio, view.leading = superview.leading + 16 e view.trailing = superview.leading + 200 con una superview larga 100pt. L'algoritmo Cassowary non riesce a trovare una soluzione e l'app si blocca con NSConstraintException. La soluzione è ridurre la priorità di uno dei constraint in conflitto a Default High (750).

Riepilogo

  • Auto Layout è il sistema di layout adattivo di Apple basato sull'algoritmo Cassowary, che risolve un sistema di vincoli lineari con priorità.
  • Constraints sono equazioni della forma view1.attribute = multiplier × view2.attribute + constant con priorità da 1 a 1000 (Required).
  • UIStackView è un contenitore che gestisce automaticamente i constraint per gli arrangedSubviews con supporto di assi, distribution e alignment.
  • NSLayoutConstraint con Anchor API è lo standard programmatico da iOS 9, riducendo il codice del 40% rispetto all'API classica.
  • Safe Area è l'area senza Dynamic Island, Notch, Home Indicator; obbligatoria per collegare i constraint top/bottom.
  • Errori comuni — translatesAutoresizingMaskIntoConstraints dimenticato, conflitto Required, Ambiguous Layout, mescolanza di anchor LTR/RTL.
  • Intrinsic Content Size e priorità (hugging 251, compression 749) controllano il comportamento degli elementi quando lo spazio disponibile cambia.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche