Präsentieren einer benutzerdefinierten Ansicht über jeder Ansicht in SwiftUIIOS

Programmierung für iOS
Guest
 Präsentieren einer benutzerdefinierten Ansicht über jeder Ansicht in SwiftUI

Post by Guest »

Ich weiß, dass es ein paar Beiträge zu ähnlichen Themen gibt, aber keiner hat in meinem Fall funktioniert.
Grundsätzlich habe ich eine komplexe Anwendung, in der es eine Hauptansicht gibt sind mehrere Panels (dargestellt in Form von .sheet oder .fullScreenCover über der Hauptansicht). Über der Hauptansicht ist jeweils nur ein Bereich aktiv (ähnlich wie bei Apple Maps).
Ich habe eine benutzerdefinierte Warnung (als Vollbild-Cover) in Form eines Modifikators erstellt, aber Immer wenn ich eine Warnung über einem Blatt anzeigen möchte, muss ich den benutzerdefinierten Warnungsmodifikator an dieses Blatt anhängen. Dadurch wird in der gesamten App eine Menge doppelter Code hinzugefügt, da ich jedem Blatt Modifikatoren hinzufüge und etwas ausprobiere, bei dem der Modifikator nur an die Hauptansicht gebunden ist und wann immer eine Warnung angezeigt werden soll, egal um welches Panel/Blatt es sich handelt In der Hauptansicht geöffnet, sollte über dem aktiven Blatt eine Warnung angezeigt werden.
Unten ist mein Code. Ich habe versucht, einen kleinen Beispiellaufcode zu erstellen, da meine App komplex ist:

Code: Select all

import SwiftUI

struct ContentView: View {
@State private var showSheet = false
@StateObject var viewModel: AppViewModel = AppViewModel()

var body: some View {
VStack {
Text("This is main view with multiple sheets.")
}
.padding(.bottom, 350.0)
.onAppear {
showSheet = true
}
.sheet(isPresented: $showSheet) {
SheetA().environmentObject(viewModel)
}
.customAlert(isPresented: $viewModel.showAlert) /// Wish to present an alert always from here, but the alert should be visible on top of any sheet that's open.
}
}

struct SheetA: View {
@EnvironmentObject var viewModel: AppViewModel

var body: some View {
VStack {
Text("This is sheet.")
Spacer()
Button {
viewModel.showAlertFromSheet()
} label: {
Text("Tap me")
}
}
.padding([.top, .bottom], 150.0)
.presentationDetents([.medium, .large], selection: $viewModel.panelDetent)
// Note: Works fine if I add this modifier to every sheet.  But trying to avoid that.
//.customAlert(isPresented: $viewModel.showAlert)
}
}

class AppViewModel: ObservableObject {
@Published var panelDetent: PresentationDetent = .medium

@Published var showAlert: Bool = false

func showAlertFromSheet() {
// Make http request call and show an alert on failure
self.showAlert = true
}
}
Code für benutzerdefinierte Benachrichtigung, falls Sie sie verweisen/ausführen möchten:

Code: Select all

extension View {
func customAlert(isPresented: Binding) -> some View {
return modifier(CustomAlertView(isPresented: isPresented))
}
}

struct CustomAlertView: ViewModifier {
@Binding var isPresented: Bool

init(isPresented: Binding) {
self._isPresented = isPresented
}

func body(content: Content) -> some View {
content.fullScreenCover(isPresented: $isPresented) {
alertView123.background(CustomAlertBackground())
}
.transaction { transaction in
transaction.disablesAnimations = true
}
}

private var alertView123: some View {
GeometryReader { geometry in
if self.$isPresented.wrappedValue {
VStack {
Image(systemName: "info.circle.fill").resizable().frame(width: 32.0, height: 32.0)
.padding(.top, 30).foregroundColor(Color.blue)

Text("Alert Title").foregroundColor(Color.primary).font(.title2).bold().multilineTextAlignment(.center)
.padding([.leading, .trailing], 20.0).padding(.top, 12.0)
Spacer()

Text("Alert Message").foregroundColor(Color.secondary).font(.body).multilineTextAlignment(.center)
.padding([.leading, .trailing], 20.0).padding(.top, 12.0)
Spacer()

// Buttons
}.fixedSize(horizontal: false, vertical: true).background(Color.gray.opacity(0.5))
.cornerRadius(28)
.clipped()
.padding([.leading, .trailing], 5.0)
.position(x: geometry.size.width/2, y: geometry.size.height/2)
.frame(width: 350.0)
}
}
}
}

struct CustomAlertBackground: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
return InnerView()
}

func updateUIView(_ uiView: UIView, context: Context) {}

private class InnerView: UIView {
override func didMoveToWindow() {
super.didMoveToWindow()
superview?.superview?.backgroundColor = UIColor(Color.gray.opacity(0.25))
}
}
}
Mit dem obigen Code wird die Warnung nicht angezeigt und ich erhalte die Meldung „Derzeit wird nur die Präsentation eines einzelnen Blatts unterstützt. Das nächste Blatt wird angezeigt, wenn das aktuell präsentierte Blatt verworfen wird.“ „ Fehler in Xcode. Ich möchte das Blatt nicht schließen, sondern darüber eine Ansicht (in meinem Fall eine benutzerdefinierte Benachrichtigung) anzeigen.
Was ist der beste Weg, dies zu erreichen, indem ich die Benachrichtigung als vollständig präsentiere? Bildschirmabdeckung scheint nicht zu funktionieren?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post