iOS: Duo split engages when flat (include inactive hinge), size fallback; 1.0 RC 4

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-11-09 12:20:17 -08:00
1 parent dfdd9a8ae5
commit 4f2dcb94f5
3 files changed
+20 -8

No files matched your search

+17 -6
View File
@@ -1,4 +1,5 @@
import SwiftUI
import UIKit
/// The tab bar, a navigation stack per tab, the mini player and the Now Playing sheet.
/// On an unfolded iPhone Duo the library sits on one side of the hinge and Now Playing on the other.
@@ -171,13 +172,23 @@ private struct DuoSplit<Library: View, Docked: View>: View {
private struct Cut { var vertical: Bool; var first: CGFloat; var gap: CGFloat; var second: CGFloat }
private static func cut(_ geo: GeometryProxy) -> Cut? {
guard #available(iOS 27.1, *),
let r = geo.reservedRegions(kind: .division).first(where: \.isActive)?.frame else { return nil }
let size = geo.size
let vertical = r.height >= r.width
let c = vertical
? Cut(vertical: true, first: r.minX, gap: r.width, second: size.width - r.maxX)
: Cut(vertical: false, first: r.minY, gap: r.height, second: size.height - r.maxY)
var c: Cut?
// The hinge reports inactive while the phone lies flat, so ask for inactive regions too.
if #available(iOS 27.1, *),
let r = geo.reservedRegions(kind: .division, options: .includeInactive).first?.frame {
let vertical = r.height >= r.width
c = vertical
? Cut(vertical: true, first: r.minX, gap: r.width, second: size.width - r.maxX)
: Cut(vertical: false, first: r.minY, gap: r.height, second: size.height - r.maxY)
} else if UIDevice.current.userInterfaceIdiom == .phone, size.width >= 760, size.height >= 560 {
// No region reported: only an unfolded Duo gives an iPhone this much room both ways.
// The hinge sits at the middle of the screen, not of the safe area, so place it from there.
let screenW = (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.screen.bounds.width
let half = ((screenW ?? size.width) / 2 - geo.frame(in: .global).minX).rounded()
c = Cut(vertical: true, first: half - 12, gap: 24, second: size.width - half - 12)
}
guard let c else { return nil }
// A region that doesn't leave usable room on both sides isn't a hinge worth splitting at.
return c.first > 200 && c.second > 200 ? c : nil
}