4

I can display a sheet with a custom height with detents in SwiftUI like this.

.sheet(isPresented: $showSheet) {
    MySheet()
        presentationDetents([.height(500), .large])
}

Is there a way that I can measure the exact height of my view MySheet and pass this to presentationDetents without having a fixed value? I ask because based on the user's accessibility settings the height of the view could change.

Berry Blue
  • 15,330
  • 18
  • 62
  • 113

1 Answers1

14

Approach:

  • Measure the size of the content being presented and set the value into a @State variable
  • Use GeometryReader in the background of the content being presented to measure the height of content.
  • GeometryReader is added to the background of the content being presented and not to the foreground because GeometryReader tends to expand to all the space given to it like color or shape.

Note:

  • This is one crude way to do it, happy to hear any better approaches
  • For multiline text please add .fixedSize(horizontal: false, vertical: true) to the text

Code

struct ContentView: View {
    @State private var isSheetShown = false
    @State private var sheetContentHeight = CGFloat(0)

    var body: some View {
        Button("Show sheet") {
            isSheetShown = true
        }
        .sheet(isPresented: $isSheetShown) {
            VStack {
                Text("hello line 1")
                Text("hello line 2")
                Text("hello line 3")
            }
            .background {
                //This is done in the background otherwise GeometryReader tends to expand to all the space given to it like color or shape.
                GeometryReader { proxy in
                    Color.clear
                        .task {
                            print("size = \(proxy.size.height)")
                            sheetContentHeight = proxy.size.height
                        }
                }
            }
            .presentationDetents([.height(sheetContentHeight)])
        }
    }
}
user1046037
  • 16,755
  • 12
  • 92
  • 138
  • If the text is multiline, it won't return you correct value for the height. – Takasur May 10 '23 at 22:35
  • 3
    For multiline text add `.fixedSize(horizontal: false, vertical: true)` to the `Text` so that it can grow vertically – user1046037 May 11 '23 at 14:09
  • @user1046037 you're my friggin hero. The `.fixedSize(...)` was giving me a headache for a while now. I've just been arbitrarily adding in a 80 height to offset the multilines xD – xTwisteDx May 17 '23 at 00:26
  • when switching colorScheme or moving to another app then going back, it make the view totally breaks – glemoulant Jul 17 '23 at 09:04