iOS-Resizability: wenn eine App nicht mehr weiß, auf welchem Gerät sie läuft
Fünf Designprinzipien, jedes in Code umgesetzt: Im Zeitalter der Fensterskalierung kümmert eine App nur, wie viel Platz sie hat. Mit Szenenkonfiguration, Geometrie-Callbacks, Zwei-Stufen-Strategie, Info.plist-Rotlinien und Testmatrix.
Resizability bedeutet: Das Fenster einer App lässt sich wie ein Desktop-Fenster am Rand greifen, frei ziehen und in der Größe verändern. Der Designgedanke, den Apple zu dieser Veränderung mitgibt, passt in einen Satz – eine App kümmert sich nicht mehr darum, auf welchem Gerät, in welcher Ausrichtung und auf welchem Bildschirm sie läuft. Sie kümmert sich nur darum, wie viel Platz sie gerade hat. Du definierst zwei Verhaltensweisen: wie Inhalte stehen, wenn der Platz groß ist, und wie, wenn er klein ist. Das System trägt diese Logik über alle Geräte, alle Fenstergrößen und alle Klappzustände.
Das ist keine normale API-Aktualisierung. Es ist ein Spurwechsel im Layout-Paradigma seit Bestehen von iOS. Dieser Artikel zerlegt den Designgedanken in fünf Prinzipien, setzt jedes einzelne in UIKit- und SwiftUI-Code um und endet mit einer Migrations-Roadmap und einer Testmatrix, die du direkt abarbeiten kannst.
Die Signaturen im Text sind gegen das iOS 27.1 SDK aus Xcode 27.1 abgeglichen. Das Verhalten folgt Apples Dokumentation und den WWDC-Sessions, die Quellen stehen am Ende. Der Fließtext ist eine Nacherzählung und eine technische Aufbereitung, keine Übersetzung einer bestimmten Seite.
1. Von iOS 26 zu 27: wie das Skalieren zum Standard wurde
Vor dem Designgedanken die Zeitleiste. Sie erklärt, warum die alte Vorgehensweise nicht mehr ausreicht.
| Phase | Was passiert ist | Was es für dich bedeutet |
|---|---|---|
| iPadOS 15 | Split View / Slide Over / Stage Manager | iPad bekommt Größen jenseits von Vollbild |
| iPadOS 26 | iPad im Zeitalter freier Fenster, beliebig ziehen und skalieren | Die Annahme „iPad = regular" gerät ins Wanken |
| iOS 26 SDK | UIRequiresFullScreen ist veraltet |
Kein Ausstieg aus der Skalierung über die Vollbild-Taste |
| iOS 26 SDK | iPhone-Apps skalieren auch auf iPad und in Mac-Spiegelung | „Läuft auf einem iPhone" heißt nicht mehr compact |
| iOS 27 | UIScene-Lebenszyklus ist Pflicht für Builds mit aktuellem SDK | Szenen werden das Fundament |
| iOS 27 | Systemkomponenten wie Tab-Bar und Toolbars passen sich an jedes Seitenverhältnis an | Systembausteine übernehmen die Hauptarbeit |
Der Bogen in einem Satz: Die Fenstergröße wurde von einem Aufzählungswert zu einem stetigen Wert. Früher sah eine App 375, 393, 414, 768, 1024. Jetzt greift ein Finger an den Fensterrand und zieht einmal: Die Breite kann jede Zahl zwischen 320 und der Bildschirmgrenze sein. Layout, das für diskrete Stufen festgeschrieben wurde, bricht am stetigen Wert garantiert.
2. Prinzip eins: vom „Gerätedenken" zum „Raumdenken"
Fast alles alte Layout-Wissen steht auf Gerätedenken: Das ist ein iPhone, es ist quer, also so anordnen; das ist ein iPad, also in zwei Spalten. Resizability verlangt, dieses Denken vollständig zu tauschen.
| Gerätedenken (alt) | Raumdenken (neu) | |
|---|---|---|
| Entscheidungsgrund | Gerätetyp, Ausrichtung, Bildschirmgröße | Verfügbarer Raum des aktuellen Containers |
| Layout-Anzahl | Ein Version pro Gerät | Ein Regelsatz für alle Räume |
| Neue Hardware | Vielleicht Codeänderungen und ein Release | Greift automatisch, null Änderungen |
| Klappzustände | Pro Haltung ein weiteres Interface | Ein Interface, das mit der Breite mitwächst |
| Code-Geruch | if idiom == .pad, isLandscape |
horizontalSizeClass, Containerbreite |
Die schlichteste Formulierung des Raumdenkens kommt von der WWDC: Du entwirfst nicht für jede Plattform und jede Fenstergröße einzeln. Du definierst einmal, wie Inhalte sich verhalten, wenn mehr Platz da ist und wenn weniger da ist. Das System trägt diese Logik auf jedes Seitenverhältnis. Das Drehen des Geräts ist nur ein Auslöser dieser Logik, dem Ziehen eines Fensters, dem Wechsel in Split View oder dem Aufklappen dem Wesen nach gleichartig – am Ende läuft alles auf denselben einen Punkt zu: Der verfügbare Raum hat sich verändert.
3. Prinzip zwei: Size Classes sind die neue Lingua franca
Wenn das Gerätedenken abtritt, übernimmt was den Stab? Die Size Class. Sie ist die qualitative Beurteilung des Raums durch das Framework: zwei Achsen, je zwei Wörter – compact heißt beengt, regular heißt geräumig.
Die horizontale Achse urteilt über links und rechts: Bei compact gehört der Inhalt in eine Spalte gestapelt; erst bei regular sind Spalten, Reihung und Sidebar ehrlich.
Die vertikale Achse urteilt über oben und unten: Bei compact passt das vertikale Chrome (Tab-Bar, Toolbar) nicht mehr hin, und das System stellt eine waagerechte Tab-Bar auf die schmale Kante. Bei regular halten obere und untere Leisten gleichzeitig stand.
In SwiftUI ausgelesen:
@Environment(\.horizontalSizeClass) private var hSize // UserInterfaceSizeClass?
@Environment(\.verticalSizeClass) private var vSize
if hSize == .regular {
// Links und rechts Platz: Spalten / Sidebar / zweireihig
} else {
// Links und rechts beengt: eine Spalte, gestapelt
}
In UIKit trägt traitCollection.horizontalSizeClass dieselbe Pflicht, und mit registerForTraitChanges lassen sich Änderungen gezielt abonnieren.
Es folgt die wichtigste Tabelle dieses Textes – Size Classes stehen in keiner Eins-zu-eins-Beziehung zu Gerät und Ausrichtung:
| Szene | Horizontal | Vertikal | Anmerkung |
|---|---|---|---|
| iPhone hochkant | compact | regular | Die Standardform der ganzen App |
| iPhone quer | compact | compact | Nur noch etwa 320pt hoch, Tab-Bar steht hochkant |
| iPhone-Fenster vergrößert (iOS 26+) | regular | regular | Ändert sich zur Laufzeit, nicht beim Start |
| iPad Vollbild | regular | regular | Etwa 1024pt breit |
| iPad Split View halb | regular | regular | Nur etwa 507pt breit, immer noch regular |
| iPad Slide Over | compact | compact | Eine compact-Form auf dem iPad |
| Duo Außendisplay | compact | compact | Etwa 466pt breit |
| Duo aufgeklapptes Innendisplay | regular | compact | Wechselt mit dem Klappzustand zur Laufzeit |
Lies diese Tabelle dreimal, und zwei gegen die Intuition stehende Schlussfolgerungen treten heraus: „Läuft auf einem iPhone" heißt nicht mehr compact (ein vergrößertes Fenster ist regular), und „läuft auf einem iPad" heißt nicht mehr regular (Slide Over ist compact). Weder Gerätetyp noch Ausrichtung beantworten „welches Layout soll ich jetzt benutzen". Man fragt die Size Class zur Laufzeit.
Die Tabelle korrigiert auch einen alten Glauben: Das Gerät drehen heißt nicht „das Gerät hat sich verändert". Drehen schaltet das Paar (H, V) von (compact, regular) auf (compact, compact) um und verändert einmal die Bounds. Die Struktur deines Layout-Codes bewegt sich nicht, bewegt wird nur die Eingabe. In der Zeit, in der „Ausrichtung" ein Layout-Begriff war, war sie immer eine Ersatzvariable. Der Ersatz ist weg. Es bleibt nur der Raum.
Die Size-Class-Klippe: warum eine zweite Stufe nötig ist
Size Classes sind binär und grob genug, um zu „lügen". Sieh die Klippe: iPad-Vollbild mit 1024pt und Split View halb mit 507pt sind beide (regular, regular) – aber in das eine passt eine Sidebar, in das andere nicht. Zwei Wörter können die Grad-Fragen nicht beantworten: wie viele Spalten, wie groß, Breite begrenzen oder nicht.
Die erwachsene Vorgehensweise ist deshalb ein Staffellauf über zwei Stufen: Size Classes beantworten die Richtungsfrage (eine Spalte oder geteilt), die Ingenieursstrategie beantwortet die Grad-Frage (wie viele Spalten, Hero-Größe, Lesebreite). Die zweite Stufe stafft typischerweise nach gemessener Containerbreite: Auf breiten Bildschirmen begrenzt sie den Text auf eine angenehme Zeilenlänge, oder sie leitet die Spaltenzahl aus der Mindestgröße der Inhalte ab. Seit iOS 17 kann SwiftUI mit onGeometryChange die Containergröße direkt messen und in diese Entscheidung einspeisen – auf GeometryReader brauchst du nicht zurückzugreifen.
4. Prinzip drei: Die Funktion ändert sich mit der Größe nicht, nur die sichtbare Menge
Das ist ein leicht zu übersehender, aber nicht hoch genug zu schätzender Grundsatz der Human Interface Guidelines: Wenn sich die Size Class ändert, bleibt die Funktionsmenge gleich. Es ändert sich nur „wie viel man auf einmal sieht".
Auf einem breiten Bildschirm klappt die Tab-Bar zur Sidebar auf und zeigt Sekundärziele. In einem schmalen Fenster wandern Werkzeuge niedriger Priorität ins Overflow-Menü und bleiben mit einem Tipp erreichbar. Verstecken ist Umgruppieren, nicht Löschen. Wenn eine Aktion im breiten Layout existiert und im schmalen spurlos verschwindet, ist das keine Anpassung, sondern ein fehlendes Feature. Ebenso darf es zwischen Hoch- und Querformat nicht geben „dieser Screen lässt sich nur in einer Ausrichtung komplett bedienen" – was hochkant geht, muss auch quer von vorne bis hinten aufgehen.
Die stille Anforderung an die Produktgestaltung lautet: Schreibe in der Informationsarchitektur jeder Einheit eine Priorität zu. Teilen und Primäraktionen haben hohe Priorität und sind in jeder Größe resident. Speichern und Sekundäres haben niedrige Priorität: breit resident, schmal im Overflow. Der Visibility Priority-Mechanismus der Systemkomponenten tut genau dies.
5. Prinzip vier: Min-/Max-Größen verhindern Überlappung, sie verwehren die Skalierung nicht
UIKit erlaubt es einer Szene, eine minimale und eine maximale Größe zu deklarieren. Die Semantik muss aber klar sein: Diese beiden Werte existieren, damit Elemente in kleinen Größen einander nicht überdecken und in großen nicht ausfasern. Sie sind keine Hürde, die der Nutzer nehmen muss, bevor ihm das Ziehen erlaubt wird. Sobald ein Fenster auf jede Größe gezogen werden kann, ist es deine Verantwortung, Inhalte in jeder Größe mindestens benutzbar, lesbar und überlappungsfrei zu halten. Bricht eine bestimmte Größe unvermeidlich, dann war deine Minimalgröße zu gierig – oder das Layout ist noch nicht wirklich adaptiv.
Deklariert beim Verbinden der Szene:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }
// Untergrenze: darunter beginnen sich Elemente zu überdecken.
// Obergrenze: darüber wird das Layout schlaff.
windowScene.sizeRestrictions?.minimumSize = CGSize(width: 320, height: 480)
}
Die alte Rechnung, die dazugehört: UIRequiresFullScreen ist veraltet, und wer es hält, bleibt von der Skalierung ausgeschlossen – gibt neue Displaygrößen automatisch preis. Seit dem iOS 26 SDK brauchen Apps für neue Bildschirme weder Codeänderungen noch eine erneute Einreichung; das System passt automatisch an – sofern du die Tür nicht selbst verriegelst.
6. Prinzip fünf: Lass die Systemkomponenten die Arbeit machen
Die sparsamste Strategie im Zeitalter der Resizability ist, das Umgruppieren an Systemkomponenten abzugeben. Ihr Umgang mit beliebigen Seitenverhältnissen ist robuster als jedes handgeschriebene Layout:
Tab-Bars und Toolbars: Wird das Fenster breiter, bleiben Tab-Icons in einer Zeile mit ihren Labels und halten die Bar kompakt. Wird es schmaler, wandern Werkzeuge niedriger Priorität ins Overflow-Menü. In einer News-App lässt sich „Teilen" über alle Größen anpinnen und „Später lesen" erst im Schmalen überlaufen – über Visibility Priority deklariert, ohne eine Zeile Layout-Code.
Sidebars: Seit iPadOS 26 können auch iPhone-Apps ein Sidebar-Layout wählen, wenn der Platz es erlaubt; abgesichert über
sidebar.isAvailable.NavigationSplitView: Seit iOS 26 zeigen und verbergen sich Spalten nach Platz; Spaltensichtbarkeit von Hand zu verwalten ist nicht mehr nötig.
Liquid-Glass-Systemmaterialien: Auf iOS 27 mit verbesserter Diffusion und Kantentrennung; ohne Neukompilierung geerbt.
Deine eigene UI hat hier genau eine Aufgabe: Mit diesen Bausteinen nicht zu kämpfen. Selbstgezeichnete Top-Bars müssen die Schließen- und Minimieren-Steuerung oben links meiden (über den Layout-Guide mit horizontaler Corner-Adaption). Nimm nie an, die Tab-Bar sei immer unten und die Toolbar immer oben – ihre Gestalt selbst verändert sich mit dem Raum.
7. UIKit in der Praxis: Szenenkonfiguration und Geometrie-Antwort
Szenen sind das Fundament der Resizability: Jede Szene verwaltet ihre eigene Instanz von UI und Zustand eigenständig und liefert den Kontext „wo und wie groß steht dieses UI". Seit iOS 27 müssen Builds mit aktuellem SDK den UIScene-Lebenszyklus übernehmen – das ist nicht optional.
Ein Scene-Delegate-Gerüst zum direkten Abschreiben:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }
// 1) Größenfähigkeit deklarieren: Überlappung verhindern, Skalierung nicht verwehren
windowScene.sizeRestrictions?.minimumSize = CGSize(width: 320, height: 480)
// 2) Fenster an die Szene hängen; nie UIWindow(frame: UIScreen.main.bounds)
let window = UIWindow(windowScene: windowScene)
window.rootViewController = AdaptiveRootController()
self.window = window
window.makeKeyAndVisible()
}
// 3) Geometrie-Rückruf: Ziehen, Split View, Aufklappen, externer Displaywechsel
func windowScene(_ windowScene: UIWindowScene,
didUpdateEffectiveGeometry previous: UIWindowScene.Geometry) {
let geometry = windowScene.effectiveGeometry
let size = geometry.coordinateSpace.bounds.size
// isInteractivelyResizing bedeutet: der Nutzer hält den Rand noch.
// Schwere Arbeit (Asset-Neuaufbau, Chart-Neurechnung) passiert einmal,
// wenn die Geste endet – nicht für jede Zwischengröße.
if !geometry.isInteractivelyResizing,
size != previous.coordinateSpace.bounds.size {
AssetStore.shared.rebuild(for: size)
}
}
// 4) iPadOS 26+ Stil der Fenstersteuerung (Schließen / Minimieren)
func preferredWindowingControlStyle(for scene: UIWindowScene)
-> UIWindowScene.WindowingControlStyle {
.unified
}
}
Drei Punkte verdienen Entfaltung:
isInteractivelyResizing ist die Lebensader der Zieh-Performance. Während des Ziehens meldet das System Geometrie fortlaufend. Baut ein Spiel oder eine App für jede Zwischengröße Renderressourcen neu auf, bricht die Bildrate auf der Stelle ein. Die Standardhaltung: beim Ziehen nur Leichtes aktualisieren (Constraints, Schriftgrößen), nach dem Loslassen einmal das Schwere.
Nimm Bildschirm und Größe nie über UIScreen.main. Unter Spiegelung und externen Displays ist der Hauptbildschirm die falsche Antwort. Richtige Quellen sind view.window?.windowScene?.screen, die effectiveGeometry der Szene oder die lokalen view.bounds.
Fenstersteuerung meiden. Seit iPadOS 26 trägt die Szene oben links Steuerungen zum Schließen und Minimieren. Selbstgezeichnete Top-Bars müssen sich an containerView.layoutGuide(for: .margins(cornerAdaptation: .horizontal)) binden, sonst wird dein erster Button untippbar.
8. Die View-Schicht: drei alte Muster streichen
Adaptiver UIKit-View-Code ist im Kern „drei Ersetzungen":
| Streichen | Ersetzen durch | Warum |
|---|---|---|
UIScreen.main.bounds |
view.bounds / effectiveGeometry / windowScene?.screen |
Unter Split View und Spiegelung ist der Hauptbildschirm nicht dein Fenster |
userInterfaceIdiom == .pad-Zweige |
traitCollection.horizontalSizeClass |
Der Gerätetyp trägt keine Layout-Semantik |
interfaceOrientation-Zweige |
Size Class + lokale Bounds | Ausrichtung ist ein Ergebnis des Layouts, nicht seine Ursache |
Nach dem Tausch treibt die Trait-Änderung das Layout:
class AdaptiveRootController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Bei Size-Class-Wechsel umgruppieren; Registrierung deckt auch
// Cache-Ungültigkeit ab, die automatisches Tracking nicht sieht
registerForTraitChanges([UITraitHorizontalSizeClass.self,
UITraitVerticalSizeClass.self]) { (vc: Self, _) in
vc.applyLayout()
}
}
private func applyLayout() {
switch (traitCollection.horizontalSizeClass, traitCollection.verticalSizeClass) {
case (.regular, _): useSidebarLayout()
case (.compact, _): useStackedLayout()
default: useStackedLayout()
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Wenn das Urteil feiner ist als eine Size Class: lokale verfügbare Größe
fineTune(for: view.bounds.size)
}
}
Beachte, dass viewDidLayoutSubviews / layoutSubviews fortlaufend wirken: Die Size-Class-Änderung löst die „Struktur-Umgruppierung" aus, die Bounds-Änderung die „Feinjustierung". Wer in onAppear / viewDidLoad einmal die Größe liest und behält, produziert die ersten veralteten Werte, sobald die Skalierung beginnt.
9. SwiftUI in der Praxis: überwiegend automatisch, an Schlüsselstellen unterfüttert
SwiftUI-Apps haben bei Resizability Vorsprung: Mit Xcode 27 neu kompiliert, kommt die Fenster-Skalierung automatisch, es gibt keine neue API zu übernehmen, und die neuen Liquid-Glass-Materialien werden mitgeerbt. Aber „automatisch" ist nicht „prüffrei". Der Werkzeugkasten auf SwiftUI-Seite:
@Environment(\.horizontalSizeClass)/verticalSizeClass: Entspricht dem UIKit-Trait, beantwortet die Richtungsfrage.onGeometryChange(for:of:action:): Misst den Container, beantwortet die Grad-Frage. Es liest, ohneGeometryReaders gierigen Platzgriff auszulösen, und ruft die Aktion nur auf, wenn sich der abgeleitete Wert wirklich ändert – ein natürlicher Filter für Zwischenzustände beim Ziehen.ViewThatFits: Das deklarative „nimm das erste, das passt", geeignet wenn Inhalte nach Breite die Anordnung wechseln.containerRelativeFrame(): Bemisst nach Container-Verhältnis statt absoluten Punkten; besonders nützlich für Flächen, die sich unter System-UI erstrecken sollen.NavigationSplitView: Seit iOS 26 passen sich Spaltenbreite und Spaltensichtbarkeit von selbst an; wickle nicht noch eine Handverwaltung darum.
.windowResizability(.contentMinSize): SwiftUIs Eingang für die minimale Szenengröße, das Gegenstück zusizeRestrictions?.minimumSize.
Ein typischer Staffellauf über zwei Stufen:
struct DashboardView: View {
@Environment(\.horizontalSizeClass) private var hSize
@State private var columnCount = 1
var body: some View {
ScrollView {
MetricGrid(columns: columnCount)
}
// Stufe eins: Size Class entscheidet einspaltig oder geteilt
.onChange(of: hSize) { _, new in
usesSidebar = (new == .regular)
}
// Stufe zwei: gemessene Breite entscheidet die Spaltenzahl,
// deckt 507 und 1024 ab, die beide "regular" sind
.onGeometryChange(for: CGFloat.self) { $0.size.width } action: { _, width in
columnCount = AdaptiveWindowLayoutPolicy.tier(for: width).columns
}
}
}
10. Rote Linien in Info.plist und Launch Screen
Zwei rote Linien liegen in der Projektkonfiguration. Wer eine verfehlt, detoniert erst zur Einreichung:
UIRequiresFullScreenmuss behandelt werden. Veraltet, und wer es hält, bleibt von der Skalierung ausgeschlossen. Löschen; wenn es echte Legacy-Kompatibilität braucht, mitUIRequiresFullScreenIgnoredStartingWithVersionerklären, ab welcher Version der Schlüssel ignoriert wird. Spiele geraten dadurch in diskretes Skalieren – nach jedem abgeschlossenen Ziehen wechseln sie in eine zum Maß passende neue Bildschirmkonfiguration und halten Full-Quality-Rendering.Launch Screen ist Pflicht. Seit dem iOS 27 SDK können Apps ohne konfigurierten Launch Screen die App-Store-Einreichung nicht bestehen (TN3208). In einem SwiftUI-Projekt heißt das meist, eine minimale Startbild-Konfiguration nachzureichen – nicht weiter barfuß zu laufen.
11. Anti-Pattern-Schnellreferenz
Bevor du Code anfasst, durchsuche die Codebasis nach diesen Mustern. Jeder Treffer ist zurückzuzahlende Schuld:
| Anti-Pattern | Warum es bricht | Ersetzen durch |
|---|---|---|
UIScreen.main.bounds |
Unter Split View / Spiegelung nicht dein Fenster | Lokale view.bounds oder Szenengeometrie |
UIDevice.current.userInterfaceIdiom-Zweige |
Gerätetyp hat keine Layout-Semantik | horizontalSizeClass |
interfaceOrientation / Ausrichtungs-Notifications |
Meldet Gerätehaltung, nicht Fensterform | Size Class + lokale Bounds |
size.width > 600 selbstgebaute Breakpoints |
Umgeht Trait-Semantik, verfehlt Split-Zwischenzustände | Ingenieur-Staffelungsstrategie + onGeometryChange |
Größe einmal in onAppear lesen |
Skalierung ist fortlaufend, der Cache veraltet sofort | Trait- / Geometrie-Rückrufe |
| Breites Layout nur fürs iPad | Ein iPad in Slide Over benimmt sich wie ein Telefon | Breite und schmale Logik beide vom Raum ausgelöst |
.frame(height: 480) fest für Karten / Hero |
In kurzen Fenstern rutscht der Text aus dem ersten Screen | Höhe container-relativ oder adaptiv |
12. Migrations-Roadmap
Vier Schritte, geordnet nach Risiko und Ertrag:
Phase 1 · Entschärfen (zuerst, blockiert die Einreichung): UIRequiresFullScreen löschen, Launch Screen nachreichen, bestätigen, dass der UIScene-Lebenszyklus in Benutzung ist. Diese drei Punkte sind harte Tore, unabhängig von Entwurfsqualität; fehlen sie, klemmt Build oder Review direkt.
Phase 2 · Anti-Patterns räumen: Mit der Tabelle aus Abschnitt 11 UIScreen.main, Idiom-/Ausrichtungs-Zweige und handgemachte Breiten-Breakpoints codebasisweit ersetzen. Das Ziel ist nicht „es läuft", sondern die Layout-Eingabe auf Raumsemantik zu vereinheitlichen.
Phase 3 · Die zwei Stufen bauen: Für inhaltsgetriebene Screens die Strategie „Size Class entscheidet Richtung + gemessene Breite entscheidet Grad" etablieren und jede nackte Schwelle dort zusammenführen. Auf breiten Bildschirmen die Textbreite begrenzen; eine Zeile über 85 Zeichen ist ein Lesbarkeitsbug.
Phase 4 · Testen systematisieren: Die Matrix aus Abschnitt 13 Größe für Größe durchgehen und die Ergebnisse als Regressionspunkte einfrieren.
13. Testmatrix
Resizability-Tests werden nicht nach Gerätelisten gemacht, sondern nach Raumformen. Jede Form muss beantworten: Ist die Funktion vollständig, wird Inhalt beschnitten, ist Chrome tippbar?
| Raumform | Was zu prüfen ist |
|---|---|
| Schmalste nutzbare Breite (nahe minimumSize) | Überlappen Elemente, sind primäre Buttons tippbar |
| Standard-Telefonbreite | Grundlinie des Standardlayouts |
| Telefon quer | Unter vertical compact: Tab-Bar hochkant, erster Screen vollständig |
| Telefonfenster bis regular vergrößert | Übernehmen Spalten, bleibt Zustand erhalten |
| Split View halb / Slide Over | Zwei Raumverhalten auf demselben iPad |
| Extrem breit-flache und hoch-schmale Verhältnisse | Trägt die Hintergrund-Erstreckung, reißt der Inhalt nicht |
| Duo außen und aufgeklappt | Verlaufen Layout und Zustand beim Klappen stetig |
| iPhone-Spiegelung / externes Display | Stimmen Bildschirm- und Größenabfragen |
Werkzeugseitig bieten Xcodes Device Hub und Previews einen Fenster-Resize-Modus; ein Zug am Rand ändert die Größe fortlaufend. Spiegelung und externe Displays gehören auf echte Hardware.
14. Häufige Fragen
Warum lässt sich meine iPhone-App plötzlich auf Fenstergröße ziehen?
Kein Fehler – neues Verhalten seit dem iOS 26 SDK: iPhone-Apps, die auf dem iPad oder in der Mac-Spiegelung laufen, haben frei skalierbare Fenster. Das zugehörige Layout-Signal ist, dass die horizontale Size Class von compact auf regular kippt. Der alte Code if idiom == .phone produziert in solchen Fenstern das falsche Layout. Frag die Size Class.
Reichen Size Classes? Warum zusätzlich die Breite messen?
Sie reichen nicht, und die Klippe ist real. iPad-Vollbild und Split View halb sind beide (regular, regular), ihre Breiten unterscheiden sich jedoch um das Doppelte – in das eine passt eine Sidebar, in das andere nicht. Size Classes entscheiden Richtung (einspaltig oder geteilt), gemessene Breite entscheidet Grad (wie viele Spalten, wie groß). Beides ist ein Staffellauf, keine Wahl.
Wenn ich minimumSize deklariere, können Nutzer dann nicht kleiner ziehen?
minimumSize ist die Untergrenze, ab der dein Inhalt anfängt sich zu überdecken; Nutzer können nicht darüber hinaus ziehen. Das ist ein Überlappungsschutz, kein Feature-Gate gegen die Skalierung. Was du schuldest, ist Bedienbarkeit in jeder Größe von minimumSize bis maximumSize. Versagt eine Größe, ist die Anpassung unfertig – nicht einfach das Minimum erhöhen.
Was passiert, wenn ich UIRequiresFullScreen lösche?
Die App nimmt am Fenster-Skalieren teil, die seit iOS 26+ erwartete Vorgabe. Wer Legacy-Kompatibilität braucht, kann mit UIRequiresFullScreenIgnoredStartingWithVersion die Ignorier-Ab-Version angeben; Spiele geraten in diskretes Skalieren und wechseln nach jedem Ziehen in eine passende Bildschirmkonfiguration, was die Renderqualität eher wahrt.
Was muss eine SwiftUI-App wirklich tun?
Neu kompilieren, und die Skalierungsunterstützung ist da; keine neue API zu übernehmen. Prüfe stattdessen: Code, der auf UIScreen-Zeit-Annahmen baut; Größenurteile, die nur Size Classes nutzen ohne Messungs-Unterfütterung; Komponenten mit festem Frame, die in extremen Seitenverhältnissen reißen. Das Framework regelt das Makro. Die reißende Komponente ist meist die, die du selbst festgenagelt hast.
Quellen und Weiterlesen
Offizielle Quellen: WWDC25 Session 282 „Make your UIKit app more flexible", WWDC26 Session 278 „Modernize your UIKit app", die Abschnitte Layout und Designing for iPhone Duo der Human Interface Guidelines, die Dokumentation zu UISceneSizeRestrictions und UIWindowScene.Geometry sowie die Technotes TN3192: Migration von der verworfenen UIRequiresFullScreen-Kennung und TN3208: Anforderungen an den Launch Screen.
Weiterlesen auf dieser Site: Um zu sehen, wie derselbe Gedanke auf einem konkreten Gerät von Anfang bis Ende landet, lies Oberflächen für das iPhone Duo: vom Layout zum Code. Für die andere Seite – dass auch Daten mit dem Raum schrumen – sieh den Ratgeber zur persönlichen Basislinie. Weitere Fragen zu Produkt und Anpassung stehen in den häufigen Fragen.
Weiterlesen
Diese Ideen in Stress HRV ausprobieren
Im App Store ladenDiese Notizen teilen Produktgedanken für Wellness. Sie sind keine medizinische Beratung.