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?
CodePudding user response:
For that use selection
binding of presentationDetents(_:selection:)
.
struct SheetView: View {
@State var selectedDetent: PresentationDetent = .medium
var body: some View {
Button {
selectedDetent = selectedDetent == .large ? .medium : .large
} label: {
Text("Toggle")
}
.presentationDetents(selectedDetent == .large ? [.large] : [.medium, .large], selection: $selectedDetent)
}
}
CodePudding user response:
Could it just be that you're missing withAnimation
from your showSheet = true