#if os(iOS) import SwiftUI import UIKit /// Bittet die Seitenleiste, den Inhalt zu **überlagern** statt ihn zu verdrängen. /// /// `UITabBarControllerSidebar.preferredLayout` steht ab Werk auf `automatic`, /// und das löst sich laut Apples eigener Beschreibung je nach Gerät anders auf: /// auf iOS zu `overlap` — die Leiste schwebt als eigene Fläche über dem Inhalt — /// und auf macOS zu `tile`, wo sie den Inhalt zur Seite schiebt und selbst am /// Fensterrand klebt. Das ist der Unterschied, den man zwischen iPad und Mac /// sieht, und er kommt nicht aus dieser App. /// /// **Unter Mac Catalyst gemessen: es hilft dort nicht.** Der Griff sitzt /// richtig — zum Beweis hat derselbe Weg die Leiste auf Kommando ganz /// ausgeblendet —, aber `overlap` wird auf dem Mac stillschweigend verworfen /// und es bleibt bei `tile`. Der Aufruf bleibt trotzdem stehen: er ist die /// richtige Bitte, er kostet nichts, und sollte „Designed for iPad" sich näher /// am iPhone-Bau verhalten als Catalyst, greift er dort. /// /// SwiftUI reicht die Eigenschaft nicht durch, also wird der zuständige /// `UITabBarController` gesucht. Gesucht wird vom eigenen Platz aus nach oben /// bis zur Wurzel und von dort nach unten — die Leiste liegt in der /// SwiftUI-Sicht *über* uns, nicht unter uns, und die reine Elternkette führt /// deshalb an ihr vorbei. struct SidebarOverlapRequest: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> UIViewController { Probe() } func updateUIViewController(_ controller: UIViewController, context: Context) {} /// Ein Controller, der nichts zeigt und nur da ist, um im Baum zu stehen. private final class Probe: UIViewController { override func didMove(toParent parent: UIViewController?) { super.didMove(toParent: parent) apply() } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // Ein zweites Mal: beim ersten Anhängen steht der // Tab-Controller noch nicht zwingend im Baum. apply() } private func apply() { guard let controller = Self.tabBarController(from: self) else { return } guard controller.sidebar.preferredLayout != .overlap else { return } controller.sidebar.preferredLayout = .overlap } private static func tabBarController(from start: UIViewController) -> UITabBarController? { var root = start while let parent = root.parent { root = parent } return search(root) } private static func search(_ controller: UIViewController) -> UITabBarController? { if let found = controller as? UITabBarController { return found } for child in controller.children { if let found = search(child) { return found } } return nil } } } #endif