ios – Presenting customized alert on prime of all of the views together with sheets or full display screen cowl

0
2
ios – Presenting customized alert on prime of all of the views together with sheets or full display screen cowl


I’m looking for a working answer for this downside 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 prime of all of the views, however the customization of the alert components is so restricted attributable to which I needed to create a customized alert. My alert comprises icons and styled buttons.

My app is advanced, so sharing a brief pattern working instance. The app presents a MainView and there’ll all the time be a sheet over it whose peak may be adjusted (typically full display screen cowl as an alternative of sheet). Alerts may be introduced by MainView and by any of the sheet views. In any case, I need alert to be all the time on prime of sheet view (or full display screen cowl)

Right here I attempted presenting an alert (take into account Coloration.black.opacity.. as an alert in my code under) in 2 other ways.

  • A technique is utilizing ZStack in ContentView and even in MainView. In each
    the circumstances, the AlertView opens behind SheetView and does not cowl
    SheetView.
  • Second method is utilizing an AlertViewModifier in SheetView.
    With this, the alert will get introduced throughout the SheetView (as an alternative of
    over SheetView) such that I’m nonetheless in a position to work together with the
    MainView and in addition in a position to regulate peak of SheetView.

Pattern code:

import SwiftUI

class SampleViewModel: ObservableObject {
    @Printed var showSheet = false
    @Printed var panelDetent = PresentationDetent.medium
    @Printed var showZStackAlert: Bool = false
}

struct ContentViewA: View {
    @StateObject var viewModel: SampleViewModel = .init()
    @State non-public var showSheet: Bool = false
    var physique: some View {
        NavigationStack {
            ZStack {
                if viewModel.showZStackAlert {
                    AlertView()
                }
                
                MainView()
            }
        }
        .environmentObject(viewModel)
    }
}

/// Presenting customized alert from foremost ContentView
struct AlertView: View {
    var physique: some View {
        VStack {
            Coloration.black.opacity(0.5).edgesIgnoringSafeArea(.all)
        }
    }
}

struct MainView: View {
    @EnvironmentObject var viewModel: SampleViewModel
    @State non-public var showSheet: Bool = false
    var physique: some View {
        ZStack {
//            if viewModel.showZStackAlert {
//                AlertView()
//            }
//            
            VStack {
                Textual content("That is foremost 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
    @Surroundings(.presentationMode) non-public var presentationMode
    @State non-public var showAlert: Bool = false
    
    var physique: some View {
        NavigationStack {
            ZStack {
                Coloration.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 ? Coloration.black.opacity(0.5) : nil)
            .overlay(self.$isPresented.wrappedValue ? alertContent() : nil)
            .animation(.default, worth: self.$isPresented.wrappedValue)
    }
    
    @ViewBuilder
    non-public func alertContent() -> some View {
        GeometryReader { geometry in
            if self.$isPresented.wrappedValue {
                VStack {
                    /// Contents of alert view
                }
                .fixedSize(horizontal: false, vertical: true)
                .place(x: geometry.measurement.width/2, y: geometry.measurement.peak/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 prime of sheet view?

LEAVE A REPLY

Please enter your comment!
Please enter your name here