From afcdb1de5fd1e39d17811697a9458cceb29164a2 Mon Sep 17 00:00:00 2001 From: marchidalgo Date: Mon, 23 Feb 2026 12:23:07 +0100 Subject: [PATCH 1/7] refactor: consolidate sheet detent logic Refactor the view modifiers for intrinsic height sheets to unify and simplify logic by introducing `intrinsicSheetDetents`. This new helper function abstracts the platform-specific sheet detent logic, handling size checking and applying appropriate presentation detents more efficiently. The change cleans up repeated code, removing conditional compilation blocks and reducing potential for maintenance errors. --- .../ViewModifiers/IntrinsicHeightSheet.swift | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift index 35e3a5a9..764bc5bd 100644 --- a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift +++ b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift @@ -63,21 +63,14 @@ struct IntrinsicHeightDetentView_ForBool: View { @Binding var isPresented: Bool let onDismiss: (() -> Void)? - #if canImport(Darwin) @State var sheetSize: CGSize = .zero - #endif var body: some View { hostView .sheet(isPresented: $isPresented, onDismiss: onDismiss) { contentView() - #if canImport(Darwin) .getCGSize($sheetSize) - .presentationDetents([.height(sheetSize.height)]) - .fixedSize(horizontal: false, vertical: true) - #else - .presentationDetents([.medium]) - #endif + .intrinsicSheetDetents(sheetSize) } } } @@ -94,20 +87,12 @@ struct IntrinsicHeightDetentView_ForItems CGSize) { @@ -116,6 +101,18 @@ private struct CGSizeKey: PreferenceKey { } private extension View { + @ViewBuilder + func intrinsicSheetDetents(_ sheetSize: CGSize) -> some View { + if sheetSize.height > 0 { + self + .presentationDetents([.height(sheetSize.height)]) + .fixedSize(horizontal: false, vertical: true) + } else { + self + .presentationDetents([.medium]) + } + } + /// Sets the `View`'s size to the passed `Binding` /// - Parameter viewSize: The `Binding` where to store the value /// - Returns: a `SwiftUI.View`. @@ -130,4 +127,3 @@ private extension View { ) } } -#endif From f5a27f3d77d9f14f29c257a96af8c71bd5fcf0b6 Mon Sep 17 00:00:00 2001 From: marchidalgo Date: Mon, 23 Feb 2026 12:34:05 +0100 Subject: [PATCH 2/7] fix: conditionally compile presentationDetents on non-Darwin platforms Add conditional compilation to `intrinsicSheetDetents` method, wrapping `fixedSize` modifier with `#if canImport(Darwin)`. This ensures correct behavior on non-Darwin platforms, which might not support `.fixedSize` for `.presentationDetents`. This change is crucial for maintaining cross-platform compatibility and avoiding unexpected layout behavior. --- .../SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift index 764bc5bd..a32f4100 100644 --- a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift +++ b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift @@ -104,9 +104,14 @@ private extension View { @ViewBuilder func intrinsicSheetDetents(_ sheetSize: CGSize) -> some View { if sheetSize.height > 0 { + #if canImport(Darwin) self .presentationDetents([.height(sheetSize.height)]) .fixedSize(horizontal: false, vertical: true) + #else + self + .presentationDetents([.height(sheetSize.height)]) + #endif } else { self .presentationDetents([.medium]) From c0da5306c0993012508985a55c4625335494b77a Mon Sep 17 00:00:00 2001 From: marchidalgo Date: Mon, 23 Feb 2026 14:19:37 +0100 Subject: [PATCH 3/7] fix: reset sheet size on presentation and improve size handling Reset the sheet size to zero on presentation to guarantee an update to the correct size when the sheet is shown again. This fix is crucial for preventing incorrect size carry-over in repeated presentations. Improve size update logic by introducing a function to check for significant size changes before updating. This prevents unnecessary updates and reduces potential re-rendering loops, especially on Darwin platforms. Compensate for the bottom space on Android to ensure the sheet opens with the intended appearance. --- .../ViewModifiers/IntrinsicHeightSheet.swift | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift index a32f4100..6bc3ad03 100644 --- a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift +++ b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift @@ -67,6 +67,14 @@ struct IntrinsicHeightDetentView_ForBool: View { var body: some View { hostView + .onChange(of: isPresented) { _, newValue in + guard newValue else { + return + } + #if canImport(Darwin) + sheetSize = .zero + #endif + } .sheet(isPresented: $isPresented, onDismiss: onDismiss) { contentView() .getCGSize($sheetSize) @@ -85,6 +93,14 @@ struct IntrinsicHeightDetentView_ForItems Bool { + let widthDiff = abs(current.width - next.width) + let heightDiff = abs(current.height - next.height) + return widthDiff > Self.sizeChangeTolerance || heightDiff > Self.sizeChangeTolerance + } + @ViewBuilder func intrinsicSheetDetents(_ sheetSize: CGSize) -> some View { if sheetSize.height > 0 { @@ -110,11 +135,17 @@ private extension View { .fixedSize(horizontal: false, vertical: true) #else self - .presentationDetents([.height(sheetSize.height)]) + .presentationDetents([.height(sheetSize.height + Self.androidBottomCompensation)]) #endif } else { + #if canImport(Darwin) self .presentationDetents([.medium]) + #else + // Android: avoid opening at .medium to prevent visible jump down when real height arrives. + self + .presentationDetents([.height(1)]) + #endif } } @@ -127,8 +158,26 @@ private extension View { Color.clear .preference(key: CGSizeKey.self, value: proxy.size) }.onPreferenceChange(CGSizeKey.self) { value in - viewSize.wrappedValue = value + updateSheetSize(viewSize, newSize: value) } ) } + + func updateSheetSize(_ viewSize: Binding, newSize: CGSize) { + guard newSize.height > 0 else { + return + } + + #if canImport(Darwin) + if isSignificantSizeChange(from: viewSize.wrappedValue, to: newSize) { + viewSize.wrappedValue = newSize + } + #else + // Android: lock to the first measured value to avoid recomposition loops. + guard viewSize.wrappedValue.height <= 0 else { + return + } + viewSize.wrappedValue = newSize + #endif + } } From 413a6af4b1264e70ddeed84582e16be579737af3 Mon Sep 17 00:00:00 2001 From: marchidalgo Date: Mon, 23 Feb 2026 15:19:31 +0100 Subject: [PATCH 4/7] refactor: remove platform-specific code for uniform behavior Remove platform-specific (Darwin/Android) conditional checks to streamline and simplify the intrinsicHeightSheet implementation. The decision ensures consistent behavior across all platforms and removes unnecessary complexity, providing a cleaner and more maintainable codebase. --- .../ViewModifiers/IntrinsicHeightSheet.swift | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift index 6bc3ad03..4be09063 100644 --- a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift +++ b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift @@ -71,9 +71,7 @@ struct IntrinsicHeightDetentView_ForBool: View { guard newValue else { return } - #if canImport(Darwin) sheetSize = .zero - #endif } .sheet(isPresented: $isPresented, onDismiss: onDismiss) { contentView() @@ -97,9 +95,7 @@ struct IntrinsicHeightDetentView_ForItems Date: Mon, 23 Feb 2026 15:59:01 +0100 Subject: [PATCH 5/7] refactor: remove redundant checks and refactor sheet presentation Removes redundant onChange checks for sheet presentation state, relying instead on the default behavior of SwiftUI's sheet presentation. Refactors sheet presentation logic to accommodate both Darwin and non-Darwin platforms using a conditional compilation approach. This simplifies code and improves maintainability while ensuring consistent behavior across platforms. --- .../ViewModifiers/IntrinsicHeightSheet.swift | 48 ++++++++----------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift index 4be09063..ad8e66a4 100644 --- a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift +++ b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift @@ -67,16 +67,16 @@ struct IntrinsicHeightDetentView_ForBool: View { var body: some View { hostView - .onChange(of: isPresented) { _, newValue in - guard newValue else { - return - } - sheetSize = .zero - } .sheet(isPresented: $isPresented, onDismiss: onDismiss) { contentView() + #if canImport(Darwin) + .getCGSize($sheetSize) + .presentationDetents([.height(sheetSize.height)]) + .fixedSize(horizontal: false, vertical: true) + #else .getCGSize($sheetSize) .intrinsicSheetDetents(sheetSize) + #endif } } } @@ -91,16 +91,16 @@ struct IntrinsicHeightDetentView_ForItems Bool { - let widthDiff = abs(current.width - next.width) - let heightDiff = abs(current.height - next.height) - return widthDiff > Self.sizeChangeTolerance || heightDiff > Self.sizeChangeTolerance - } - @ViewBuilder func intrinsicSheetDetents(_ sheetSize: CGSize) -> some View { if sheetSize.height > 0 { - #if canImport(Darwin) - self - .presentationDetents([.height(sheetSize.height)]) - .fixedSize(horizontal: false, vertical: true) - #else self .presentationDetents([.height(sheetSize.height + Self.androidBottomCompensation)]) - #endif } else { self - .presentationDetents([.medium]) + .presentationDetents([.height(1)]) } } @@ -158,8 +145,13 @@ private extension View { return } - if isSignificantSizeChange(from: viewSize.wrappedValue, to: newSize) { - viewSize.wrappedValue = newSize + #if canImport(Darwin) + viewSize.wrappedValue = newSize + #else + guard viewSize.wrappedValue.height <= 0 else { + return } + viewSize.wrappedValue = newSize + #endif } } From 02386f3548257d64d4cdd62962c479058c4dab93 Mon Sep 17 00:00:00 2001 From: marchidalgo Date: Mon, 23 Feb 2026 16:17:08 +0100 Subject: [PATCH 6/7] refactor: simplify intrinsicSheetDetents logic and adjust compensation Simplify the logic for intrinsicSheetDetents by removing the conditional height check. Adjust the androidBottomCompensation from 24.0 to 20.0 for better UI consistency across platforms. --- .../SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift index ad8e66a4..12343882 100644 --- a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift +++ b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift @@ -113,17 +113,12 @@ private struct CGSizeKey: PreferenceKey { } private extension View { - static var androidBottomCompensation: CGFloat { 24.0 } + static var androidBottomCompensation: CGFloat { 20.0 } @ViewBuilder func intrinsicSheetDetents(_ sheetSize: CGSize) -> some View { - if sheetSize.height > 0 { - self - .presentationDetents([.height(sheetSize.height + Self.androidBottomCompensation)]) - } else { - self - .presentationDetents([.height(1)]) - } + self + .presentationDetents([.height(sheetSize.height + Self.androidBottomCompensation)]) } /// Sets the `View`'s size to the passed `Binding` From 6249d69c63ba9b9e9847bf25633ae5dd5a2fb9f0 Mon Sep 17 00:00:00 2001 From: marchidalgo Date: Mon, 23 Feb 2026 17:18:40 +0100 Subject: [PATCH 7/7] refactor: remove unnecessary code for non-Darwin platforms Simplify the SwiftUI intrinsic height sheet implementation by removing code specific to non-Darwin platforms, ensuring that only Darwin-specific logic is applied. The `intrinsicSheetDetents` and related compensation logic were removed as they were redundant, simplifying the logic focused on `canImport(Darwin)`. --- .../ViewModifiers/IntrinsicHeightSheet.swift | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift index 12343882..6450e3e2 100644 --- a/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift +++ b/Sources/BSWInterfaceKit/SwiftUI/ViewModifiers/IntrinsicHeightSheet.swift @@ -69,13 +69,10 @@ struct IntrinsicHeightDetentView_ForBool: View { hostView .sheet(isPresented: $isPresented, onDismiss: onDismiss) { contentView() - #if canImport(Darwin) .getCGSize($sheetSize) .presentationDetents([.height(sheetSize.height)]) + #if canImport(Darwin) .fixedSize(horizontal: false, vertical: true) - #else - .getCGSize($sheetSize) - .intrinsicSheetDetents(sheetSize) #endif } } @@ -93,13 +90,10 @@ struct IntrinsicHeightDetentView_ForItems some View { - self - .presentationDetents([.height(sheetSize.height + Self.androidBottomCompensation)]) - } - /// Sets the `View`'s size to the passed `Binding` /// - Parameter viewSize: The `Binding` where to store the value /// - Returns: a `SwiftUI.View`.