1

I am trying to present a view programmatically from the appdelegate. The basic idea it's to present a view so that the user must enter a code to unlock the app. This code works

func applicationWillResignActive(application: UIApplication) {
    var storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    var vc : PasswordViewController = storyboard.instantiateViewControllerWithIdentifier("PasswordViewController") as PasswordViewController
    let navigationController = UINavigationController(rootViewController: vc)
    self.window?.rootViewController?.presentViewController(navigationController, animated: true, completion: nil)
}

But have a problem. If the user press home inside another view (like the one shown on the picture) the password viewcontroller does not shows and I get a warning

Warning: Attempt to present UINavigationController: 0x7f8c2263c480 on UITabBarController: 0x7f8c2256ad60 whose view is not in the window hierarchy!

left view presents ok the view, right one not, note that right one is accessed with the + button and it's modal

enter image description here

Any help will be much welcome!

Alejandro Luengo
  • 1,256
  • 1
  • 17
  • 27

1 Answers1

3

I wrote an app that did something like this - upon resuming the application the user would be prompted for a PIN or return to the login screen.

I think the trick for this is not to try to present a viewController modally - I just overlaid the entire window with a UIView that intercepts all touches and blocks everything behind it.

Ordinarily I just program every subview into a UIView manually. For example:

class PasswordView:UIView{
    override init(frame: CGRect) {
        super.init(frame: frame)
        var disabler = UIView(frame: frame)
        disabler.backgroundColor = UIColor(white: 1.0, alpha: 0.2)
        self.addSubview(disabler)

        var redBar = UIView(frame: CGRectMake(0,22,frame.width,44))
        redBar.backgroundColor = UIColor.redColor()
        self.addSubview(redBar)
        //etc... and add other elements using code
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

This is my preferred means to manage all my views because I maintain the most amount of control, but you might also look into loading from an .xib

At any rate... in my app I created this view in this manner:

var passCode = PasswordView(frame: GCRectZero)

func applicationDidBecomeActive(application: UIApplication) {
    passCode.removeFromSuperview()
    passCode = PasswordView(frame: self.window!.bounds)
    self.window!.addSubview(passCode)
}

I would recommend you give the appDelegate a dedicated var passCode = PasswordView(frame: GCRectZero) so that you can remove it from the superview before adding another. This way you don't stack up a ton of views.

Community
  • 1
  • 1
GCRev
  • 31
  • 2