Open saff1x opened 1 month ago
Hey @saff1x, opaque popup is just a fullscreen cover, I can't control what it covers. Apple also doesn't give me any way to place any custom views above the system views like sheets, popovers and navbar, so no control there either. If you know of a way to bypass that restriction, you are most welcome to commit a PR. Have a nice day
I found a workaround based on this article: https://www.fivestars.blog/articles/swiftui-windows/
Not really sure what its doing and its probably not the best solution but it works for me. Hope it helps
import UIKit
import SwiftUI
import ExytePopupView
class SnackbarManager: ObservableObject{
@Published var showSnackbar: Bool = false
@Published var snackbarMessage: String = ""
static let shared = SnackbarManager()
private init() {}
func showSnackbar(message: String) {
snackbarMessage = message
showSnackbar = true
}
func dismissSnackbar() {
showSnackbar = false
}
}
struct SnackbarViewModifier: ViewModifier {
@ObservedObject var snackbarManager = SnackbarManager.shared
func body(content: Content) -> some View {
content
.popup(
isPresented: Binding(
get: { snackbarManager.showSnackbar },
set: { value in
snackbarManager.showSnackbar = value
}
),
view: {
Snackbar(message: snackbarManager.snackbarMessage)
},
customize: {
$0
.type(.toast)
.position(.bottom)
.autohideIn(4)
.dragToDismiss(true)
.useKeyboardSafeArea(true)
}
)
}
}
final class SceneDelegate: NSObject, UIWindowSceneDelegate {
var secondaryWindow: UIWindow?
func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
setupSecondaryOverlayWindow(in: windowScene)
}
}
func setupSecondaryOverlayWindow(in scene: UIWindowScene) {
let secondaryViewController = UIHostingController(
rootView:
EmptyView()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.modifier(SnackbarViewModifier())
)
secondaryViewController.view.backgroundColor = .clear
let secondaryWindow = PassThroughWindow(windowScene: scene)
secondaryWindow.rootViewController = secondaryViewController
secondaryWindow.isHidden = false
self.secondaryWindow = secondaryWindow
}
}
class PassThroughWindow: UIWindow {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard let hitView = super.hitTest(point, with: event) else { return nil }
return rootViewController?.view == hitView ? nil : hitView
}
}
And then added this in the iosApp file:
import SwiftUI
@main
struct iosApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { return true }
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
let configuration = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
if connectingSceneSession.role == .windowApplication {
configuration.delegateClass = SceneDelegate.self
}
return configuration
}
}
Hi, I want to use a toast to display error messages in my app (The toast should be at the bottom of the screen). However i noticed that when using a native .popover screen, the toast is below the popover and can't be seen. I tried using the .isOpaque(true) modifier, however that just closes the popover, which is not what I want. Is there any way to fix this? Thanks in advance.