Warning: Attempt to Present * on * Whose View Is Not in the Window Hierarchy - Swift

How to move from one view controller to another using code on a specific condition in Swift?

    if condition == true {
//use either VC Name associate or the Storyboard restoration id
//replace this with yours
if let Level2 = self.storyboard!.instantiateViewControllerWithIdentifier("MainVC") as? UIViewController
{
self.presentViewController(Level2, animated: true, completion: nil)
}

}

I think the problem is with you trying to cast the another VC to ViewController which i presume is the one that you are trying to segue from.

Make sure to have the storyboard ID and you can either type case to UIViewController to be broad or your specific VC to be specific.

Sample Image

Hope it helps.

Present a new view in SwiftUI

To show a modal (iOS 13 style)

You just need a simple sheet with the ability to dismiss itself:

struct ModalView: View {
@Binding var presentedAsModal: Bool
var body: some View {
Button("dismiss") { self.presentedAsModal = false }
}
}

And present it like:

struct ContentView: View {
@State var presentingModal = false

var body: some View {
Button("Present") { self.presentingModal = true }
.sheet(isPresented: $presentingModal) { ModalView(presentedAsModal: self.$presentingModal) }
}
}

Note that I passed the presentingModal to the modal so you can dismiss it from the modal itself, but you can get rid of it.



To make it REALLY present fullscreen (Not just visually)

You need to access to the ViewController. So you need some helper containers and environment stuff:

struct ViewControllerHolder {
weak var value: UIViewController?
}

struct ViewControllerKey: EnvironmentKey {
static var defaultValue: ViewControllerHolder {
return ViewControllerHolder(value: UIApplication.shared.windows.first?.rootViewController)

}
}

extension EnvironmentValues {
var viewController: UIViewController? {
get { return self[ViewControllerKey.self].value }
set { self[ViewControllerKey.self].value = newValue }
}
}

Then you should use implement this extension:

extension UIViewController {
func present<Content: View>(style: UIModalPresentationStyle = .automatic, @ViewBuilder builder: () -> Content) {
let toPresent = UIHostingController(rootView: AnyView(EmptyView()))
toPresent.modalPresentationStyle = style
toPresent.rootView = AnyView(
builder()
.environment(\.viewController, toPresent)
)
NotificationCenter.default.addObserver(forName: Notification.Name(rawValue: "dismissModal"), object: nil, queue: nil) { [weak toPresent] _ in
toPresent?.dismiss(animated: true, completion: nil)
}
self.present(toPresent, animated: true, completion: nil)
}
}

Finally

you can make it fullscreen like:

struct ContentView: View {
@Environment(\.viewController) private var viewControllerHolder: UIViewController?

var body: some View {
Button("Login") {
self.viewControllerHolder?.present(style: .fullScreen) {
Text("Main") // Or any other view you like
// uncomment and add the below button for dismissing the modal
// Button("Cancel") {
// NotificationCenter.default.post(name: Notification.Name(rawValue: "dismissModal"), object: nil)
// }
}
}
}
}

Attempt to present UIAlertController whose view is not in the window hierarchy (Swift 3/Xcode 8)

First create UIAlertController such an attribute.

var alertController: UIAlertController?

And you must add this in the viewDidLoad() like this:

override func viewDidLoad() {
super.viewDidLoad()

self.alertController = UIAlertController(title: "Alert", message: "Not images yet", preferredStyle: .alert)
self.alertController?.addAction(UIAlertAction(title: "Close", style: .default))
view.addSubview((alertController?.view)!)

}

So when you press signInButton and login is incorrect you must invoke.

@IBAction func signInPressed(_ sender: Any) {

if usernameTextField.text == "" || passwordTextField.text == "" {

createAlert(title: "Error in form", message: "Please enter an email and password.")

} else {

var activityIndicator = UIActivityIndicatorView()

activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
activityIndicator.center = self.view.center
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
view.addSubview(activityIndicator)
activityIndicator.startAnimating()
UIApplication.shared.beginIgnoringInteractionEvents()

PFUser.logInWithUsername(inBackground: usernameTextField.text!, password: passwordTextField.text!, block: { (user, error) in

activityIndicator.stopAnimating()
UIApplication.shared.endIgnoringInteractionEvents()

if error != nil {

self.presentedViewController?.present(self.alertController!, animated: true, completion: nil)
}
}

Attempt to present UIViewController on UIViewController whose view is not in the window hierarchy

Where are you calling this method from? I had an issue where I was attempting to present a modal view controller within the viewDidLoad method. The solution for me was to move this call to the viewDidAppear: method.

My presumption is that the view controller's view is not in the window's view hierarchy at the point that it has been loaded (when the viewDidLoad message is sent), but it is in the window hierarchy after it has been presented (when the viewDidAppear: message is sent).


Caution

If you do make a call to presentViewController:animated:completion: in the viewDidAppear: you may run into an issue whereby the modal view controller is always being presented whenever the view controller's view appears (which makes sense!) and so the modal view controller being presented will never go away...

Maybe this isn't the best place to present the modal view controller, or perhaps some additional state needs to be kept which allows the presenting view controller to decide whether or not it should present the modal view controller immediately.

Warning: Attempt to present UIAlertController: whose view is not in the window hierarchy

Use this to present Alert.

func showResponseAlert(title:String?,message:String?){
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default))
if var topController = UIApplication.shared.keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
topController.present(alert, animated: true, completion: nil)
}
}

Warning: Attempt to present * on * whose view is not in the window hierarchy - swift

At this point in your code the view controller's view has only been created but not added to any view hierarchy. If you want to present from that view controller as soon as possible you should do it in viewDidAppear to be safest.

Swift: Attempt to present UIAlertController whose view is not in the window hierarchy!

This line:

ViewController().present(alertView!, animated: true, completion: nil)

creates a new instance of ViewController and calls the present method on it. That won't work. You need to call it from a view controller that is itself presented. It looks like that code is inside ConsoleViewController, maybe you can just use self there.

SwiftUI [Presentation] Attempt to present ... on ... whose view is not in the window hierarchy

I suppose it's because by confirming the cancel you dismiss both the .confirmationDialog and the parent .sheet. I believe it doesn't hurt, but you can get rid of it like this:

            Button("Discard Changes", role: .destructive) {
DispatchQueue.main.async {
isPresentingEditView = false
}
}

..and put it here:

    .sheet(isPresented: $isPresentingEditView) {
NavigationView {
Text("DetailEditView(data: $data)")
.navigationTitle(Text("(scrum.title)"))
.toolbar {
ToolbarItemGroup(placement: .cancellationAction) {
Button("Cancel") {
isShowingConfirmationDialog = true
}

}
ToolbarItemGroup(placement: .confirmationAction) {
Button("Done") {
isPresentingEditView = false
// scrum.update(from: data)
}
}
}
// vvv Here
.confirmationDialog(
"Are you sure you want to discard your changes?",
isPresented: $isShowingConfirmationDialog
) {
Button("Discard Changes", role: .destructive) {
DispatchQueue.main.async {
isPresentingEditView = false
}
}
Button("Keep Editing", role: .cancel) {
isShowingConfirmationDialog = false
}
} message: {
Text("Are you sure you want to discard your changes?")
}
}
}

I got this warning attempt to present ViewController whose view is not in the window hierarchy when I try to present a view

If you want to show VC1 from VC3 the you not need to present it again because it is already loaded in navigation stack. you just need to dismiss or pop VC3 and VC2 from navigation stack. If you have presented it then dismiss and if you have pushed it then popped it.

Your warning's meaning : you are trying to presenting which is in the view hierarchy of navigation controller 1 but not in the view hierarchy of navigation controller 2.!!

Hope this will help :)



Related Topics



Leave a reply



Submit