iOS 将应用程序在后台运行一段时间后转到前台时出现黑屏
iOS black screen when bringing app to foreground after some time in background
我正在尝试从我们的 iOS 应用程序中删除所有故事板,因为在与 Git 的团队中工作时,它们会变得一团糟。
我现在在 AppDelegate 的 application(_:didFinishLaunchingWithOptions:)
方法中设置初始 ViewController:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let launchViewController = LaunchView()
window!.rootViewController = launchViewController
window!.makeKeyAndVisible()
[...]
return true
}
LaunchView 是一个简单的视图控制器,负责根据 he/she 是否登录将用户路由到登录或主屏幕。
在此之前,LaunchView 在 Main.storyboard
中设置为初始。
我已经从 Info.plist
文件中删除了这些行:
<key>UIMainStoryboardFile</key>
<string>Main</string>
一切正常,除非我们将应用程序留在后台几个小时而没有强行退出(我不确定需要多少时间来重现)然后将应用程序返回前台,显示全黑屏幕,就好像根控制器消失了一样。我们必须杀死应用程序并重新打开它才能使用它。
这让我发疯,因为它真的很难重现,因为如果您将应用程序留在后台几分钟,它就可以正常工作。
我怀疑它与应用程序暂停状态有关,但我不太确定。
您知道问题出在哪里吗?
谢谢!
编辑
可能与问题有关:
在 LaunchView 上,我使用以下代码将用户发送到主屏幕(如果他已登录):
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let rootVC = UIStoryboard.main.rootViewController
if let snapshot = appDelegate.window?.snapshotView(afterScreenUpdates: true) {
rootVC.view.addSubview(snapshot);
appDelegate.window?.rootViewController = rootVC
UIView.transition(with: snapshot, duration: 0.4, options: .transitionCrossDissolve, animations: {
snapshot.layer.opacity = 0;
}, completion: { (status) in
snapshot.removeFromSuperview()
})
}
else {
appDelegate.window?.rootViewController = rootVC
}
iOS 是否有可能在某个时候删除 rootViewController?
原来问题与交换 window
的 rootViewController
时涉及快照的过渡效果有关。
我删除了过渡效果并简单地更改了 rootViewController
。现在一切正常!
在代码中,我改变了这个:
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let rootVC = UIStoryboard.main.rootViewController
if let snapshot = appDelegate.window?.snapshotView(afterScreenUpdates: true) {
rootVC.view.addSubview(snapshot);
appDelegate.window?.rootViewController = rootVC
UIView.transition(with: snapshot, duration: 0.4, options: .transitionCrossDissolve, animations: {
snapshot.layer.opacity = 0;
}, completion: { (status) in
snapshot.removeFromSuperview()
})
}
else {
appDelegate.window?.rootViewController = rootVC
}
为此:
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let rootVC = UIStoryboard.main.rootViewController
appDelegate.window?.rootViewController = rootVC
谢谢大家的帮助!我希望这个答案对其他人有用。
我正在尝试从我们的 iOS 应用程序中删除所有故事板,因为在与 Git 的团队中工作时,它们会变得一团糟。
我现在在 AppDelegate 的 application(_:didFinishLaunchingWithOptions:)
方法中设置初始 ViewController:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let launchViewController = LaunchView()
window!.rootViewController = launchViewController
window!.makeKeyAndVisible()
[...]
return true
}
LaunchView 是一个简单的视图控制器,负责根据 he/she 是否登录将用户路由到登录或主屏幕。
在此之前,LaunchView 在 Main.storyboard
中设置为初始。
我已经从 Info.plist
文件中删除了这些行:
<key>UIMainStoryboardFile</key>
<string>Main</string>
一切正常,除非我们将应用程序留在后台几个小时而没有强行退出(我不确定需要多少时间来重现)然后将应用程序返回前台,显示全黑屏幕,就好像根控制器消失了一样。我们必须杀死应用程序并重新打开它才能使用它。
这让我发疯,因为它真的很难重现,因为如果您将应用程序留在后台几分钟,它就可以正常工作。 我怀疑它与应用程序暂停状态有关,但我不太确定。
您知道问题出在哪里吗?
谢谢!
编辑
可能与问题有关: 在 LaunchView 上,我使用以下代码将用户发送到主屏幕(如果他已登录):
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let rootVC = UIStoryboard.main.rootViewController
if let snapshot = appDelegate.window?.snapshotView(afterScreenUpdates: true) {
rootVC.view.addSubview(snapshot);
appDelegate.window?.rootViewController = rootVC
UIView.transition(with: snapshot, duration: 0.4, options: .transitionCrossDissolve, animations: {
snapshot.layer.opacity = 0;
}, completion: { (status) in
snapshot.removeFromSuperview()
})
}
else {
appDelegate.window?.rootViewController = rootVC
}
iOS 是否有可能在某个时候删除 rootViewController?
原来问题与交换 window
的 rootViewController
时涉及快照的过渡效果有关。
我删除了过渡效果并简单地更改了 rootViewController
。现在一切正常!
在代码中,我改变了这个:
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let rootVC = UIStoryboard.main.rootViewController
if let snapshot = appDelegate.window?.snapshotView(afterScreenUpdates: true) {
rootVC.view.addSubview(snapshot);
appDelegate.window?.rootViewController = rootVC
UIView.transition(with: snapshot, duration: 0.4, options: .transitionCrossDissolve, animations: {
snapshot.layer.opacity = 0;
}, completion: { (status) in
snapshot.removeFromSuperview()
})
}
else {
appDelegate.window?.rootViewController = rootVC
}
为此:
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let rootVC = UIStoryboard.main.rootViewController
appDelegate.window?.rootViewController = rootVC
谢谢大家的帮助!我希望这个答案对其他人有用。