Last active
November 7, 2023 10:58
-
-
Save megabitsenmzq/5267a14dd833d27ce56e9b6e2b433261 to your computer and use it in GitHub Desktop.
Presents a modal view with the "over current context" style in SwiftUI.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import SwiftUI | |
fileprivate var currentOverCurrentContextUIHost: UIHostingController<AnyView>? = nil | |
extension View { | |
public func overCurrentContext( | |
isPresented: Binding<Bool>, | |
showWithAnimation: Bool = false, | |
dismissWithAnimation: Bool = false, | |
modalTransitionStyle: UIModalTransitionStyle = .crossDissolve, | |
modalPresentationStyle: UIModalPresentationStyle = .overCurrentContext, | |
afterDismiss: (() -> Void)? = nil, | |
content: () -> AnyView | |
) -> some View { | |
if isPresented.wrappedValue && currentOverCurrentContextUIHost == nil { | |
let uiHost = UIHostingController(rootView: content()) | |
currentOverCurrentContextUIHost = uiHost | |
uiHost.modalPresentationStyle = modalPresentationStyle | |
uiHost.modalTransitionStyle = modalTransitionStyle | |
uiHost.view.backgroundColor = UIColor.clear | |
let rootVC = UIApplication.shared.windows.first?.rootViewController | |
rootVC?.present(uiHost, animated: showWithAnimation, completion: nil) | |
} else { | |
if let uiHost = currentOverCurrentContextUIHost { | |
uiHost.dismiss(animated: dismissWithAnimation, completion: {}) | |
currentOverCurrentContextUIHost = nil | |
afterDismiss?() | |
} | |
} | |
return self | |
} | |
} | |
//Example | |
struct TestView: View { | |
@State var isPresented = false | |
var body: some View { | |
Button(action: { | |
isPresented = true | |
}, label: { | |
Text("Show Modal") | |
}).overCurrentContext(isPresented: $isPresented, content: { | |
return AnyView ( //Important | |
Text("This is the content of the modal view.") | |
) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Works, but it's a little flaky. Also, using AnyView is discouraged by Apple, because SwiftUI then has trouble building its view structure.
See this answer: https://stackoverflow.com/a/72580290/4846592