It's December, and a very eventful year is coming to an end. While I haven't had much time to write posts recently, I still want to finish off this year with a small SwiftUI API I've been using quite a lot. Over the years, I've migrated a lot of UIKit code to SwiftUI, and I always wondered how to achieve dynamically adapting sheet presentation styles based on size classes. By searching around, I found out about presentationCompactAdaptation(_:). In this short post, I want to demonstrate how to use this modifier and how you can achieve size-class-adaptable sheets.
Usage
To dynamically change a sheet's modalPresentationStyle in UIKit, we need to make use of a dedicated protocol and implement one of its methods:
final class ViewController: UIViewController, UIAdaptivePresentationControllerDelegate {
func showDetail() {
let detailVC = DetailViewController()
detailVC.modalPresentationStyle = .pageSheet
// Set the delegate on the presentationController
detailVC.presentationController?.delegate = self
present(detailVC, animated: true)
}
// MARK: - UIAdaptivePresentationControllerDelegate
func adaptivePresentationStyle(
for controller: UIPresentationController,
traitCollection: UITraitCollection
) -> UIModalPresentationStyle {
// Keep popover on regular width, go full screen on compact
traitCollection.horizontalSizeClass == .compact ? .fullScreen : .pageSheet
}
}The functionality to dynamically switch presentation styles is backed by the UIAdaptivePresentationControllerDelegate protocol and by implementing adaptivePresentationStyle(for:). This combination gives you a lot of flexibility to control your modals based on the currently active traitCollection. I heavily used this pattern in my UIKit code to make sure sheets made the best possible use of the current horizontalSizeClass.
To maintain feature parity when migrating to SwiftUI, we can utilise the presentationCompactAdaptation(_:) modifier. It works by attaching the modifier to the view that you want to show as a sheet and declaring a PresentationAdaptation case you want your sheet to adopt in compact size classes.
struct ContentView: View {
// MARK: - State Properties
@State private var sheetIsPresented: Bool = false
// MARK: - Body
var body: some View {
Button("Press me") {
sheetIsPresented.toggle()
}
.sheet(isPresented: $sheetIsPresented) {
DetailView()
.presentationCompactAdaptation(.fullScreenCover)
}
}
}With this small and neat modifier, we can achieve the same behaviour as in UIKit with much less code.
Small Caveat
One thing to mention here is that the SwiftUI modifier only gives us the opportunity to change the presentation style of the sheet and only reacts to size class changes. If you want to change the behaviour of sheets based on other properties in UITraitCollection in UIKit, you would need to find other ways to do that in SwiftUI.
Conclusion
With this final post of 2025, I wanted to share a quick way of achieving dynamic sheet presentation adaptation in SwiftUI. I wish you all a good start to 2026!
Please feel free to reach out to me if you find any mistakes, or have questions or suggestions. You can find ways to contact me on my About 🙂
See you next year 👋