Page 1 of 1

Instructions on how to Create an iOS Splash Screen

Posted: Tue Oct 16, 2012 8:50 pm
by donryan
These instructions are offered to any other developers struggling with creating an effective Splash Screen for iOS and want to save the application's state between launches. The Splash Screen feature provided by LiveCode is adequate for a desktop application, but not for iOS (or Andriod). The reason is that for a desktop app, the user only launches the app once, so it makes sense to show the Splash Screen on each launch. However, in iOS, the user is constantly in and out of the app (by pressing the Home button, then pressing the app icon again). The user expects the app to pickup right where they left off the last time they used it. However, if you are using the LiveCode provided Splash Screen feature, the Splash Screen is displayed every time you run the app. This is undesirable.

I've been able to add a Splash Screen to my main stack and have complete control on when the Splash Screen is display and the amount of time it is displayed. I had to do a lot of "deep dives" through the forums and hours of trial and error to come up with a 100% workable solution and I wanted to share my findings with the community. I am using LiveCode 5.5.1 along with tmControls to develop my iPhone app.

I already had 14 cards in my main stack when I started this endeavor to build my own Splash Screen. Once you know the proper steps, it's easy to incorporate a mobile Splash Screen at anytime in the development process. Here's what I did:

- Create a new card and called it "frmSplash".
- Use the inspector pallet and change its Card Number to be 1
Note: in my case, since I'm using tmControls, I automatically had a "navbar" and "toolbar" placed at the top and bottom of the card. These are shared controls that will be displayed on all new cards created.
- Import your Splash Screen images using the IDE "Import as Control" function.
Note: I imported 2 images (Splash & Splash@2x) onto the card, one image for the regular display and a larger image for the retina display.
- Next, select each image individually and choose Object --> Group Selected
- Go to the inspector pallet, Basic Properties.
- Rename the grouped image accordingly.
Note: I used "grpSplash" and "grpSplash@2x" to distinguish between both groups.
- Place a check in the "Behave Like Backgroud" and UNcheck the "Shared Group".
- Next I added code to the card "frmSplash"

Code: Select all


-- Both these global variables are set in the preOpenStack script (detailed in the next code section)
global gsFirstCard
global gbRetina

on preOpenCard
  --------
  --> this only contains the tmControls initialization script
  -------
end preOpenCard

on openCard
   --> Set the Splash Screen graphics for display
   if gbRetina is false then
      set the visible of group "grpSplash@2x" to false
      set the left of group "grpSplash" to 0
      set the top of group "grpSplash" to 0
   else
      set the visible of group "grpSplash" to false
      set the left of group "grpSplash@2x" to 0
      set the top of group "grpSplash@2x" to 0
   end if
   --> Hide the toolbars
   set the visible of group "navbar" to false
   set the visible of group "toolbar" to false
   --> Show either the Splash screen or else immediately load the desired card
   if gsFirstCard is "FirstTime" then
      put "frmMain" into gsFirstCard
      send "finishSplash" to me in 2.5 seconds  --> you can adjust the time you want the Splash Screen displayed here
   else
      finishSplash
   end if
end openCard


on finishSplash
   --> Go to the appropriate screen
   lock screen for visual effect
   set the visible of group "navbar" to true
   set the visible of group "toolbar" to true
   go card gsFirstCard
   unlock screen with visual effect dissolve very fast
end finishSplash

The other component to make this work is contained in the Stack Script. I've got code placed in the preOpenStack and in the closeStack. I'll start with the closeStack code -- this is where you save the current state of your variables to a text file whenever the stack is closed. Here is what I am using:

Code: Select all


ON closeStack
   ------------------------------------------
   ---|  Save the state of the current card to a file  |---
   ------------------------------------------
   put specialfolderpath("documents") & "/last_state.txt" into tLastState
   --> Save the current card number:
   put the num of THIS card into line 1 of URL("file:" & tLastState)
   --> Save the global variables: 
   put gbRetina into line 2 of URL("file:" & tLastState)
   put gbEditMode into line 3 of URL("file:" & tLastState)
   put gbEditLesson into line 4 of URL("file:" & tLastState)
   put gnLessonID into line 5 of URL("file:" & tLastState)
   put gnDuration into line 6 of URL("file:" & tLastState)
   put gnCourseID into line 7 of URL("file:" & tLastState)
   put gsCourse into line 8 of URL("file:" & tLastState)
   put gaTempData into line 9 of URL("file:" & tLastState)
   put the name of this card into line 10 of URL("file:" & tLastState)
END closeStack

Obviously, most of these items are specific to my application, but the first line is what creates your state file in the Documents folder of your app (where you are allowed to freely write). The other important item is the last line where I am storing the card name of the last card used. This is what I need to restore so that the user can start where they left off.

Below is the final piece, the preOpenStack code:

Code: Select all


--> These globals are used to pass information to the Splash Screen
global gsFirstCard
global gbRetina

ON preopenstack
   ------------------------------------------
   ---|  Restore the state of the Last Card opened  |---
   ------------------------------------------
   IF the environment is "mobile" THEN
      get item 1 of iPhoneDeviceResolution() --> NOTE: possible parameters are 320,480 -- 640,960 -- 640,1136
      IF it is 320 THEN
         put false into gbRetina
      ELSE
         put true into gbRetina
      END IF
   END IF

   put specialfolderpath("documents") & "/last_state.txt" into tLaststate

   --> File check: if none, then this is the first time app has opened, show the Splash Screen
   IF there is not a file tLastState THEN
      put "FirstTime" into gsFirstCard
      go to card "frmSplash"
      exit preOpenStack
   END IF

   --> File found: restore the previous state
   put line 1 of URL("file:" & tLastState) into tTargetCard
   put line 2 of URL("file:" & tLastState) into gbRetina
   put line 3 of URL("file:" & tLastState) into gbEditMode
   put line 4 of URL("file:" & tLastState) into gbEditLesson
   put line 5 of URL("file:" & tLastState) into gnLessonID
   put line 6 of URL("file:" & tLastState) into gnDuration
   put line 7 of URL("file:" & tLastState) into gnCourseID
   put line 8 of URL("file:" & tLastState) into gsCourse
   put line 9 of URL("file:" & tLastState) into gaTempData
   set the itemdel to quote
   put item 2 of line 10 of URL("file:" & tLastState) into gsFirstCard
   set the itemdel to comma

   --> Load Splash screen: it will take care of loading the correct screen
   go to card "frmSplash"  

   --> Delete the file: if the phone is reset or user force-quits apps, this will cause the Splash screen to be shown again
   delete URL("file:" & tLastState)

END preOpenStack

That's it. It's working for me and I am VERY happy about it. I hope this will help other developers struggling with this issue.

Re: Instructions on how to Create an iOS Splash Screen

Posted: Fri Jun 21, 2013 8:56 am
by jacque
Glad you got it working. The only thing I'd add is when reading and writing the status file, it would be more efficient to read the file only once and put it into a variable, then read the line info from that. That way you only need to read from disk once, which will save some overhead. Do the same when writing the values back, collect all the data in a variable and then put the whole thing into the file at once.