Michael Nicht - WikiCommons

This blog post is about a learning made yesterday, as part of the preparation of releasing a new mobile application for IOS. I will however also discuss the general topic of creating a splash screen for both IOS and Android using FMX.

The splash screen

What is a splash screen? It is a full size image that is shown while your application starts up.

Android

On Android it is simple… Android do not understand the concept of a splash screen.

So the trick here is simply to let your application only auto create a simple form, containing the graphics material and text you want for your splash screen, and when it has displayed, automatically create your applications main form and other modules, after which the splash screen form closes itself.

The following is one example of how to make an Android splash screen.

Since a mobile application may start up in portrait or landscape mode, it may be wise to provide a splash screen that works well in both orientations, unless you have locked the application to one orientation only.

One way to support both orientations, is to have two images on the splash screen form, one for portrait mode and one for landscape mode. Then make the one that match the orientation visible and let it stretch to fill the form, which in itself

// Load in the main application form and close the splashscreen.
procedure TfrmSplash.LoadMainForm;
begin
     frmMain:=TfrmMain.Create(Application);
     frmMain.Show;
     Application.MainForm:=frmMain;
     Close;
end;

// At creation of the splash screen form, make a timer that reasonably quickly loads the main form.
// Make sure that both portrait and landscape images scales to fit the form size.
procedure TfrmSplash.FormCreate(Sender: TObject);
begin
     tmrStartup.Enabled:=false;
     tmrStartup.Interval:=750;
     imgPortrait.Align:=TAlignLayout.Client;
     imgLandscape.Align:=TAlignLayout.Client;
end;

// When the splash screen form is resized, we can detect its orientation
// portrait vs landscape based on the width/height ratio of the form
// which follows the size of the mobile device screen.
// Present the relevant orientation image.
procedure TfrmSplash.FormResize(Sender: TObject);
begin
     // Check if orientation changed.
     imgLandscape.Visible:=Screen.Width>Screen.Height;
     imgPortrait.Visible:=not imgLandscape.Visible;
end;

// The code for the OnPaint event handler of both portrait and landscape splash screen images.
// When one of the splash screen images has been painted, start the timer
// that will load the main form, unless it has already been started.
procedure TfrmSplash.imgPortraitPaint(Sender: TObject; Canvas: TCanvas;
  const ARect: TRectF);
begin
     tmrStartup.Enabled := not FInitialized;
end;

// When the timer runs out, disable it, and attempt start of the main form.
procedure TfrmSplash.tmrStartUpTimer(Sender: TObject);
begin
     tmrStartup.Enabled:=false;
     if not FInitialized then
     begin
          FInitialized:=true;
          LoadMainForm;
     end;
end;

This will provide you a nice splash screen for Android.

IOS

IOS is different in the sense that it does support showing a predefined image file as a splash screen or launch screen as it is named in IOS.

In fact it is possible in 10.4.2 to define splash screen images for both dark and light theme and in two different resolutions, for respectively iPhone and iPad.

You could do follow the same scheme as shown for Android, and make your own splash form, but it is not endorsed nor recommended by Apple to do so. Instead you should define static images, following some fairly strict guidelines regarding contents on the image, and the size of the uncompressed image.

IOS will then cache your splash screen image automatically, first time you start the application. The splash screen will thus show faster the next many times you open your application on IOS.

This link explains the various different resolutions of iPhones and which one of 2x and 3x resolutions is used for the splash screen for a particular iPhone or iPad: https://ivomynttinen.com/blog/ios-design-guidelines

Being lazy, just to see some sort of splash screen show up, I decided to simply use the same image file for both the 2x and 3x resolution. And that was a mistake!

What happened was that regardless of what I did, my older iPhone 6 test device only popped up a white background as launch screen, and not the image as I had expected.

That mystified me quite much. Searching high and low, it seems there is a bug in IOS in regards to the cache of launch and icon images not being cleared when you reinstall an application, why you will continue to see the same old icons or launch images, even though you updated your application.

The trick here is to uninstall your app from your device, turn your device off and on, then install your app.

However even that trick did not work. My image did not popup as a launch screen.

The solution came when I browsed the Project/Deployment page. In it I could clearly see that there were only a deployed image for the type iPhone_Launch3x, which is for iPhone 6 plus and newer iPhones. My older iPhone 6 should have iPhone_Launch2x defined.

So why is it not defined, when I very definitely have defined an image for 2x for iPhone?

The reason is that a specific file name can only occur ONCE for each deployment platform (IOS, Android, Win 32 etc). The last defined one wins and thus the definition of iPhone_Launch2x gets lost in the deployment definition.

The solution is that you MUST use different file names for each image and icon. You can’t be lazy and reuse the same one multiple times. You can however make a copy of the same image and give it a unique filename and refer to that if you wish to.

Obviously the real solution is to provide the resolution correct images for 2x and 3x and for iPhone and iPad, in which case you in any case will end up with 4 unique image files (8 if you also do a dark theme variation).

 912 total views,  2 views today

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.