我正在尝试从 appdelegate 以编程方式呈现 View 。它的基本思想是呈现一个 View ,以便用户必须输入代码才能解锁应用程序。此代码有效
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)
}
但是有个问题。如果用户在另一个 View (如图所示)中按下主页,密码 View Controller 不会显示,我会收到警告
警告:尝试在 UITabBarController:0x7f8c2256ad60 上呈现 UINavigationController:0x7f8c2263c480,其 View 不在窗口层次结构中!
左 View 呈现好的 View ,右 View 不是,请注意右 View 是通过 + 按钮访问的,它是模态的
非常欢迎任何帮助!
请您参考如下方法:
我编写了一个执行类似操作的应用程序 - 在恢复应用程序时,系统会提示用户输入 PIN 码或返回登录屏幕。
我认为这样做的诀窍不是尝试以模态方式呈现 viewController - 我只是用 UIView 覆盖整个窗口,该 UIView 拦截所有触摸并阻止它后面的所有内容。
通常我只是手动将每个 subview 编程到 UIView 中。例如:
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)
}
}
这是我管理所有 View 的首选方式,因为我保留了最多的控制权,但您也可以查看 loading from an .xib
无论如何......在我的应用程序中,我以这种方式创建了这个 View :
var passCode = PasswordView(frame: GCRectZero)
func applicationDidBecomeActive(application: UIApplication) {
passCode.removeFromSuperview()
passCode = PasswordView(frame: self.window!.bounds)
self.window!.addSubview(passCode)
}
我建议您给 appDelegate 一个专用的 var passCode = PasswordView(frame: GCRectZero) 以便您可以在添加另一个之前将其从 super View 中删除。这样您就不会堆积大量 View 。
