I’m looking for a working resolution for this drawback for a very long time however can not seem to get any options on SO working in my case. SwiftUI’s ‘.alert’ modifier appears to current itself on high of all of the views, however the customization of the alert parts is so restricted as a result of which I needed to create a customized alert. My alert incorporates icons and styled buttons.
My app is complicated, so sharing a brief pattern working instance. The app presents a MainView and there’ll all the time be a sheet over it whose top may be adjusted (typically full display cowl as a substitute of sheet). Alerts may be introduced by MainView and by any of the sheet views. In any case, I would like alert to be all the time on high of sheet view (or full display cowl)
Right here I attempted presenting an alert (take into account Colour.black.opacity.. as an alert in my code under) in 2 alternative ways.
- A technique is utilizing ZStack in ContentView and even in MainView. In each
the instances, the AlertView opens behind SheetView and would not cowl
SheetView. - Second approach is utilizing an AlertViewModifier in SheetView.
With this, the alert will get introduced throughout the SheetView (as a substitute of
over SheetView) such that I’m nonetheless capable of work together with the
MainView and in addition capable of modify top of SheetView.
Pattern code:
import SwiftUI
class SampleViewModel: ObservableObject {
@Revealed var showSheet = false
@Revealed var panelDetent = PresentationDetent.medium
@Revealed var showZStackAlert: Bool = false
}
struct ContentViewA: View {
@StateObject var viewModel: SampleViewModel = .init()
@State personal var showSheet: Bool = false
var physique: some View {
NavigationStack {
ZStack {
if viewModel.showZStackAlert {
AlertView()
}
MainView()
}
}
.environmentObject(viewModel)
}
}
/// Presenting customized alert from major ContentView
struct AlertView: View {
var physique: some View {
VStack {
Colour.black.opacity(0.5).edgesIgnoringSafeArea(.all)
}
}
}
struct MainView: View {
@EnvironmentObject var viewModel: SampleViewModel
@State personal var showSheet: Bool = false
var physique: some View {
ZStack {
// if viewModel.showZStackAlert {
// AlertView()
// }
//
VStack {
Textual content("That is major view with all the time one sheet displayed")
}
}
.onAppear {
self.showSheet = true
}
.sheet(isPresented: $showSheet) {
SheetView().environmentObject(viewModel)
}
// Extra sheets
//.sheet(isPresented: $showSheetA) {
//SheetViewA().environmentObject(viewModel)
//}
}
}
struct SheetView: View {
@EnvironmentObject var viewModel: SampleViewModel
@Setting(.presentationMode) personal var presentationMode
@State personal var showAlert: Bool = false
var physique: some View {
NavigationStack {
ZStack {
Colour.mint.opacity(0.1).edgesIgnoringSafeArea(.all)
VStack {
Button {
viewModel.showZStackAlert = true
// self.showAlert = true
} label: {
Textual content("Faucet me to open alert")
}
}
}
}
.presentationDetents([.medium, .large], choice: $viewModel.panelDetent)
.interactiveDismissDisabled(true)
.presentationBackgroundInteraction(.enabled)
.alertView(isPresented: $showAlert)
}
}
/// Presenting customized alert utilizing Alert View Modifier
struct AlertViewModifier: ViewModifier {
@Binding var isPresented: Bool
init(isPresented: Binding) {
self._isPresented = isPresented
}
func physique(content material: Content material) -> some View {
content material
.animation(nil, worth: self.$isPresented.wrappedValue)
.overlay(self.$isPresented.wrappedValue ? Colour.black.opacity(0.5) : nil)
.overlay(self.$isPresented.wrappedValue ? alertContent() : nil)
.animation(.default, worth: self.$isPresented.wrappedValue)
}
@ViewBuilder
personal func alertContent() -> some View {
GeometryReader { geometry in
if self.$isPresented.wrappedValue {
VStack {
/// Contents of alert view
}
.fixedSize(horizontal: false, vertical: true)
.place(x: geometry.dimension.width/2, y: geometry.dimension.top/2)
.body(minWidth: 350.0, maxWidth: 350.0)
}
}
}
}
extension View {
func alertView(isPresented: Binding) -> some View {
return modifier(AlertViewModifier(isPresented: isPresented))
}
}
How can I current AlertView all the time on high of sheet view?