I would like a certain view to start as a half-screen sheet, but when it’s done with some loading, it should transform into a full-screen sheet.
So in UIKit my solution would be that:
let vc = UIViewController()
vc.view.backgroundColor = .red
vc.sheetPresentationController?.detents = [.medium(), .large()]
self.present(vc, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
vc.sheetPresentationController?.animateChanges {
vc.sheetPresentationController?.selectedDetentIdentifier = .large
}
}
That works fine in UIKit… but is this also somehow possible in SwiftUI?
Something similar in SwiftUI could look like the following:
struct ContentView: View {
@State var showSheet = false
var body: some View {
Button {
showSheet = true
} label: {
Text("Show-Sheet")
}
.sheet(isPresented: $showSheet, content: {
SheetView()
})
}
}
struct SheetView: View {
@State var showFullSheet = false
var body: some View {
Button {
withAnimation {
showFullSheet.toggle()
}
} label: {
Text("Toggle")
}
.presentationDetents(showFullSheet ? [.large] : [.medium, .large])
}
}
This basically works, but the problem is that the transition between half and full is NOT animated. I’d need it animated though. Is this somehow solvable in SwiftUI?
Cause I guess wrapping my presented view in a UIViewController that then hosts my existing SwiftUI View would not be an option, as the presentation part would still be done by swift-ui, right?
2
Answers
First of all use
selection
binding ofpresentationDetents(_:selection:)
to keep track of your
selectedDetent
state. The reason you are facing this animation issue is when you setsheet
tolarge
you are setting allow detents set only with[.large]
so it’s not animating and directly jumping to large. To overcome this issue I have added@State
property to update allow detents withpresentationDetents
modifier. Now if you updatedetents
set
as soon as you update yourselectedDetent
state then also it won’t show animation, so to fix this issue I have added a one-second delay to updatedetents
and this will fix your animation issue.Could it just be that you’re missing
withAnimation
from yourshowSheet = true