I'd like to use .fullScreenCover()
or .sheet()
to present a View, depending on the current horizontalSizeClass
.
If starting the following code in an iPhone (in portrait mode = .compact
) or in an iPad (= .regular
), the View is correctly displayed in a Sheet (iPhone) or in a FullScreenCover (iPad).
However when using SplitScreen mode on an iPad (and thus switching between .compact
and .regular
the View remains in the container it was originally displayed.
How can I correctly update this when switching between sizes on-the-fly?
struct ContentView: View {
@Environment(\.horizontalSizeClass) var horizontalSizeClass
var body: some View {
Group {
Text("hidden behind modal")
}
.modal(isPresented: .constant(true)) {
if horizontalSizeClass == .regular {
Rectangle()
.fill(Color.red)
.edgesIgnoringSafeArea(.all)
} else {
Rectangle()
.fill(Color.blue)
.edgesIgnoringSafeArea(.all)
}
}
}
}
struct Modal<ModalContent: View>: ViewModifier {
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@Binding var isPresented: Bool
@ViewBuilder let modalContent: ModalContent
func body(content: Content) -> some View {
if horizontalSizeClass == .regular {
content
.fullScreenCover(isPresented: $isPresented) {
modalContent
.overlay {
Text("horizontalSizeClass: regular")
}
}
} else {
content
.sheet(isPresented: $isPresented) {
modalContent
.overlay {
Text("horizontalSizeClass: compact")
}
}
}
}
}
extension View {
public func modal<Content: View>(isPresented: Binding<Bool>, @ViewBuilder content: @escaping () -> Content) -> some View {
modifier(Modal(isPresented: isPresented, modalContent: content))
}
}