apache / cordova-ios

Apache Cordova iOS
https://cordova.apache.org/
Apache License 2.0
2.16k stars 988 forks source link

Hide the startup screen programmatically & Show loading animation on startup screen #946

Closed angelofan closed 1 year ago

angelofan commented 4 years ago

Problem

What is expected to happen?

I can hide the splash screen programmatically. There should be a loading animation on the initial screen.

What does actually happen?

I can't find any way to hide the splash screen programmatically now. There is no loading animation on the splash screen.

Information

Every time I start the App in my project, I need to log in automatically. After the login is successful, I hide the splash screen and ROOT to the home page. Now I can't find any way to hide the splash screen programmatically.

When I set the auto-hide splash screen in config.xml, if the login is performed faster, a short white screen will be displayed. If I turn off the auto-hide splash screen, when I have successfully logged in and navigate ROOT, about The splash screen was hidden after 3 seconds.

What should I do?

Command or Code

Environment, Platform, Device

cordova-ios@6.1.0

Version information

Checklist

breautek commented 4 years ago

I'm not sure if this changed in cordova-ios@6 but this is what I do in my apps:

config.xml:

<preference name="AutoHideSplashScreen" value="false" />

This will make it so the splashscreen never disappears until you explicitly tell it to, which you can via javascript:

navigator.splashscreen.hide();

This allows you to control when to hide the splash screen. For example in my app, before I show my own UI I first check if the user has stored credentials, and if so load the main screen first. Otherwise load the login screen. Only then I hide the splashscreen.

There should be a loading animation on the initial screen.

I think android supports this, but not sure about iOS. Do note that splash screens are images that gets displayed, so there will be a brief period where there is going to be a still image. This is the time between app launch and native code actually executing.

While the splashscreen code has been migrated away from the plugin, I believe the documentation still applies

angelofan commented 4 years ago

@breautek Thanks for your reply, I still have some questions.

navigator.splashscreen.hide();

How to import navigator?


The documentation for cordova-plugin-splashscreen is written like this:

ShowSplashScreenSpinner (boolean, defaults to true): Set to false to hide the splash screen spinner.

<preference name="ShowSplashScreenSpinner" value="false"/>

Note: Does not work on Browser or Windows platforms.

I did not set ShowSplashScreenSpinner to false. When I used cordova-plugin-splashscreen, Spinner was displayed on the splash screen, but now it is not displayed.

breautek commented 4 years ago

How to import navigator?

navigator is an object provided by the webview. Cordova simply just adds onto the object. No import should be necessary. If you're using a framework on top of cordova, you may have to refer to their documentation.

I did not set ShowSplashScreenSpinner to false. When I used cordova-plugin-splashscreen, Spinner was displayed on the splash screen, but now it is not displayed.

This may be a bug, but I don't have apple hardware to test with so I'm afraid I won't be helpful here.

dpogue commented 4 years ago

I did not set ShowSplashScreenSpinner to false. When I used cordova-plugin-splashscreen, Spinner was displayed on the splash screen, but now it is not displayed.

The spinner on the splashscreen is no longer support in Cordova-iOS 6.0 due to the move to Launch Storyboards.

breautek commented 4 years ago

Sounds like a workaround to the spinner then is a webview-based implementation.

The native splashscreen could be hidden after a webview-based splashscreen is loaded in, which has the flexibility of adding whatever what you want.

However, I would rather this be handled at the app level, not at the framework level.

angelofan commented 4 years ago

If the static image of the splashscreen stays too long without a spinner, the user may immediately shut down the App, especially for new users who have just downloaded the App.

If there is no better solution, I will consider hiding the splashscreen after starting the WebView, then display some animations so that the user will not think the app is unresponsive.

In general, users prefer to wait while loading animations. If the screen is displayed for too long, the user will think that the application is unresponsive.

angelofan commented 4 years ago

These changes should be described in the documentation.

breautek commented 4 years ago

I know Apple's intention behind storyboards is for you to build a replication of the UI, with content unfilled. I don't think they intend to have animations happening here. They explain their rationale

But doing what they suggest is difficult when you don't build your UI with the native tooling, because we aren't using native UI.

So I think, the best alternative is to hide the native splashscreen as soon as possible, even if that just simply reveals a web-based splashscreen with a spinner.

And I agree this should be documented, and I'll leave this open for this reason. PRs are welcome.

angelofan commented 4 years ago

After loading the WebView, a page with the same background as the splashscreen image is displayed. This page has an animation similar to the spinner, and then close the splashscreen programmatically to hide this page.

If an auto-hide splashscreen is set, you can set a timeout on this page, and then automatically hide this "fake" splash screen page at the set time.

Intuitively, this is ideal, this can be seen as a splashscreen with spinner displayed immediately after WebView is started.

michaelhodgins commented 4 years ago

I have the same problem; on Android, calling navigator.splashscreen.hide() hides the splash screen correctly. On iOS (with Cordova-ios 6.1.0), calling navigator.splashscreen.hide() does nothing. The value of SplashScreenDelay seems to take effect regardless of the value of AutoHideSplashScreen.

shaywiin commented 4 years ago

@michaelhodgins same issue here. I have checked source code of splashscreen on cordova-ios 6. Calling hide() will hide the splashscreen after SplashScreenDelay seconds.

To hide the splashscreen when app was ready, set AutoHideSplashScreen to True and SplashScreenDelay to a low number

erisu commented 4 years ago

@michaelhodgins What version of cordova-plugin-splashscreen do you have installed?

I suspect you still have the plugin cordova-plugin-splashscreen installed for Android.

As iOS 6.x has the splashscreen code integrated into its core, and if you are using an older version of the splashscreen plugin, it might be possible that there is conflicts. I had also noticed before the .hide() method not working if an older version of the plugin was used.

I would recommend checking that you have installed cordova-plugin-splashscreen@6.0.0. This major version of the plugin removed the iOS related code.

Also make sure to use Cordova-iOS 6.1.0 as it contains some SplashScreen fixes.

If you have it installed, I would also recommend trying with a clean start as there might be leftover files conflicting.

After this, npm install to refetch all dependencies, cordova prepare to make sure all plugins and platforms are re-added/installed

NOTE: this will clean out and reinstall platforms and plugins.. If you have applied manual customization to any of the code in these folders it would be lost.

@Shay-repos this might also apply to you.

AdriVanHoudt commented 4 years ago

I'm using cordova-ios 6.1.0 and cordova-plugin-splashscreen 6.0.0 and it seems that trying to manually hiding the splash screen with

    <preference name="AutoHideSplashScreen" value="false" />
    <preference name="SplashScreenDelay" value="100000000" />

doesn't work. (it used to work with < 6)

When I remove the SplashScreenDelay it does work.

    <preference name="AutoHideSplashScreen" value="false" />
    <!-- <preference name="SplashScreenDelay" value="100000000" /> -->
brassier commented 3 years ago

We're seeing the same. We have cases where we want hide the splash screen ourselves during startup, but we also have the SplashScreenDelay as a backstop, to handle some other startup scenarios. With the latest plugin it seems like you get one or the other. You can't manually call .hide() unless you get rid of the SplashScreenDelay setting.

brassier commented 3 years ago

In case anyone else is like us, desiring both the ability to call .hide() and have a backup plan (SplashScreenDelay / AutoHideSplashScreen), the good news is there doesn't seem to be a negative impact of calling .hide() twice. That allows you to make a poor-man's AutoHideSplashScreen in your app. Just do something like below:

  1. In Config.xml, remove SplashScreenDelay and set AutoHideSplashScreen to false. This will allow .hide() to actually work.
  2. Call .hide() where you want to hide the splash screen immediately
  3. To get a poor-man's Auto-Hide, throw another .hide() in a timer, as a backup plan (if your primary hide doesn't execute for whatever reason). Below is an ionic-type version for reference.
    Observable.timer(15000).subscribe(()=>{
        this.splashScreen.hide();
    });
string-lzc commented 3 years ago

Actually, .hide() only works when I removed both SplashScreenDelay and AutoHideSplashScreen.

"cordova-ios": "^6.1.1"
"cordova-plugin-splashscreen": "^5.0.2"

In case someone use the same version facing the same problem.

dpogue commented 1 year ago

I've marked this issue as stale because it's been over a year with no further comments. If this is still an issue in the latest cordova-ios version and an up-to-date iOS version, please let us know. Otherwise, this issue will be closed.

dpogue commented 1 year ago

Closing as stale.