💭 Auto-Adjust SwiftUI Sheet Height to Fit Content

Get weekly handpicked updates on Swift and SwiftUI!

TL;DR: In SwiftUI, dynamically adjust sheet height to fit its content by using GeometryReader to measure content height and passing it to presentationDetents. Ensure smooth resizing with techniques like .id() and pre-measurements to avoid jitter.

Overview

In SwiftUI development, you can enable a Sheet’s height to dynamically adjust to its content by combining GeometryReader with background, and passing the calculated height to presentationDetents. Below are detailed steps and key implementation techniques.

Example Code

Complete sample code is available here.

Usage Example

Swift
struct ContentView: View {
    @State private var showSheet = false
    var body: some View {
        Button("Show Sheet") {
            showSheet.toggle()
        }
        .adaptiveSheet(isPresented: $showSheet) {
            Text("Dynamic Height Content")
                .frame(maxWidth: .infinity, minHeight: 300)
        }
    }
}

Implementation Steps

1. Measure View Height

Use GeometryReader in combination with background to measure the actual height of the content view:

swift


复制代码
.background(
    GeometryReader { proxy in
        Color.clear
            .task {
                // Capture the height of the subview
                subHeight = proxy.size.height
            }
    }
)
  • Color.clear ensures that the layout is not visually affected.
  • .task binds the height to a variable in real time.

2. Dynamically Adjust Sheet Height

Bind the subview’s height to presentationDetents:

Swift
.sheet(isPresented: $isPresented) {
    sheetContent
        .presentationDetents([.height(subHeight)])
}
  • .height(subHeight) ensures the Sheet height adjusts dynamically with content changes.

Key Considerations

1. Prevent Initial Height Jitter

To avoid height jitter when the Sheet is first presented, pre-measure the content size using a hidden background.

2. Handle Dynamic Height Updates

Use .id() to ensure the view properly refreshes when the height changes:

Swift
.sheet(isPresented: $isPresented) {
    sheetContent
        .id(subHeight)
        .presentationDetents([.height(subHeight)])
}

3. Support for Adaptive Layouts

Optimize content for different screen sizes using ViewThatFits:

Swift
ViewThatFits {
    CompactContentView()
    FullContentView()
}

References:

By following these techniques, you can create Sheets in SwiftUI that adapt their height seamlessly to fit dynamic content, providing a polished and responsive user experience.