简体   繁体   中英

iOS App Goes to Black Screen

I am using a Launch Screen storyboard as well as a Main storyboard in my Swift app. Sometimes the app will show the launch storyboard and then go to a black screen. Other times it correctly goes to the Main storyboard entry point. It almost seems like it is build-dependent in that if I clean and rebuild a few times, a build pop out that behaves properly. Any ideas what may be causing this?

To add some clarification:

  • The SplashScreen.storyboard is set in the target settings (good question).
  • This happens both on real devices and in simulator BUT NOT ALWAYS.
  • I am not doing any networking (synchronous or otherwise) in this stage
  • The blackout seems to happen only when transitioning to one specific view
  • The code for the view's viewWillDisplay and such executes even when blacked out, just nothing VISIBLE is displayed

This might help: I put in the following code in the offending view:

override func viewDidAppear(animated: Bool) {
    print(self.view.layer.bounds.width);
    print(self.view.layer.bounds.height);

}

When the black screen issue occurs, I get 260 and 17. When the view presents correctly, I get the 5s (simulator) dimensions of 320 and 568. Does that help anyone help me?

I finally solved this. After weeks of battling it and trying everything from ripping ALL of my code out, it turns out that the view outlet for my view in the storyboard had become double-linked to both "View" and one of my text fields in that view. Like this:

在此处输入图像描述

I have since deleted the linkage to the text field, but show the correct linkage here:

在此处输入图像描述

Interestingly, I am unable to reproduce this accidental connection in the UI, so I am not sure how that even happened. Anyway, I hope this helps others that might come across this.

I was faced with the same issue in my device. I managed to fix it by setting the application's main interface via xcode: MyApplicationMain InterfaceLaunchScreen.storyboard (or Main.storyboard ).

在此处输入图像描述

Cheers! :)

I'd say the problem is this line:

    dispatch_async(dispatch_get_main_queue(), {
        self.performSegueWithIdentifier("toWelcomeView", sender: self);
    });

You're trying to do a segue to another view while this view has not yet appeared (view will appear). That's very iffy, and that's why sometimes it is in fact failing. I'm a bit surprised that you don't report seeing an error message in the Console warning that you're trying to segue from a view controller whose view is not yet in the interface.

As an interim measure, you might move your call to self.RetrieveRegistration() into viewDidAppear: and see if that helps.

But in the long term, you're just going about this the wrong way. Your goal seems to be to launch into one view controller under some circumstances and into another under other circumstances. The place to put all that logic is up front in applicationDidFinishLaunching , so that your rootViewController itself is different depending on the situation.

For example, imagine the following very simple situation: our storyboard contains just two view controller, RegistrationViewController and RootViewController (with a storyboard identifier "root" ), with a presentation segue from the first to the second. In RegistrationViewController we ask for registration info, such as a "username" , which we place in the NSUserDefaults. Then we segue to the RootViewController. All well and good, but our goal hereafter is that the user should never see RegistrationViewController again . This is easily taken care of in the app delegate:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    if let rvc = self.window?.rootViewController {
        if NSUserDefaults.standardUserDefaults().objectForKey("username") as? String != nil {
            self.window!.rootViewController = rvc.storyboard!.instantiateViewControllerWithIdentifier("root")
        }
    }
    return true
}

Make sure your first View Controller (in my case Navigation Controller) is Initial Controller. Find more details here .

Also, make sure when connecting Initial and Second Controller with Segue you press "Root View Controller" Relationship as you can see on picture here .

I hope it helps!

I fixed this issue by adding this property-value pair to the Info.plist file in the array of values inside Application Scene ManifestScene ConfigurationApplication Session RoleItem 0 (Default Configuration) .

<key>UISceneStoryboardFile</key>
<string>Main</string>

That above value is actually present in Info.plist by default, I had accidentally deleted it some time back.

对我来说,我的问题是我不小心删除了 Info.plist 中的“Application Scene Manifest”,请确保它在那里!

I have encountered the same issue today and after debugging for 2hr I got the fix

There are a few things to keep in mind.

  1. Storyboard name should be the same in the following areas:
    • Targets > 'Main target' > General > Deployment info > Main Interface
    • Targets > 'Main target' > Build Settings > UIKit Main Storyboard File Base Name
    • Info.plist > Application Scene Manifest > Scene Configuration > Application Session Role > Item 0 > Storyboard Name
  2. Make sure just below your Storyboard identifier, "Is Initial View Controller" is checked on your main/default ViewController in the storyboard you have set above.
  3. If you have deleted main.storyboard and using another storyboard as your Main Interface or the view hierarchy debugger isn't showing anything it means you have to manually set it as root in SceneDelegate .

To do that refer following code of SceneDelegate.swift

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    window = UIWindow(windowScene: windowScene)
    let sb = UIStoryboard(name: "HomeLanding", bundle: nil)
    let vc = sb.instantiateViewController(withIdentifier: "HomeLandingVC")
    window?.rootViewController = vc
    window?.makeKeyAndVisible()
}

Note: Setting window = UIWindow(frame: UIScreen.main.bounds) will break UISceneSession system, that's why we are setting it from current scene

  1. Now you have to set sceneConfig delegate class in your AppDelegate

To do that refer to the following code of AppDelegate.swift

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    let config = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
    config.delegateClass = SceneDelegate.self
    return config
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM