How to Create a Splash Screen With SwiftUI
Learn to build a splash screen that uses animation and SwiftUI to go beyond the typical static launch screen and keeps users interested while the app loads. By Rony Rozen.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How to Create a Splash Screen With SwiftUI
20 mins
Oh, the wonderful splash screen — a chance for developers to go wild with fun animations as the app frantically pings API endpoints for the critical data it needs to function. The splash screen, as opposed to a static, animation-free launch screen, can play an important role in an app: Keeping users interested while they wait for the app to start.
This tutorial will guide you step by step from an app with no splash screen to one with a cool splash screen that will be the envy of others. So, what are you waiting for?
Getting Started
In this tutorial, you’ll enhance an app called Fuber. Fuber is an on-demand ride-sharing service that allows passengers to request Segway drivers to transport them to different locations in urban environments.
Fuber has grown rapidly and now serves Segway passengers in over 60 countries, but it faces opposition from numerous governments as well as Segway unions for its use of contract Segway drivers. :]
Use the Download Materials button at the top or bottom of the page to download the starter project for this tutorial. Then, open the starter project and take a look around.
As you can see in ContentView.swift, all the app currently does is show SplashScreen
for two seconds, then fade it away to reveal a MapView
.
The splash screen lives in its own module: SplashScreen.swift. You can see that it has a Fuber-blue background with a “F ber” label that’s waiting for you to add the animated ‘U’.
Build and run the starter project.
You’ll see a not-very-exciting static splash screen that transitions into the map (Fuber’s main screen) after a few seconds.
You’ll spend the remainder of this tutorial transforming this boring static splash screen into a beautifully-animated screen that will make your users wish the main screen would never load. Take a look at what you’ll build:
Understanding the Composition of Views and Layers
The new and improved SplashScreen
will consist of several subviews, all conveniently organized in a ZStack:
- The grid background consisting of tiles of a smaller “Chimes” image, which comes with the starter project.
- The “F ber” text, with room for the animated
FuberU
. - The
FuberU
, which represents the circular white background for the ‘U’. - A
Rectangle
representing the square in the middle ofFuberU
. - Another
Rectangle
representing the line that goes from the middle ofFuberU
to its outer edge. - A
Spacer
view to make sure that theZStack
size will cover the entire screen.
Combined, these views create the Fuber ‘U’ animation.
The starter project provides the Text
and Spacer
views. You’ll add the rest of the views in the following sections.
Now that you know how you’ll compose these layers, you can start creating and animating the FuberU
.
Animating the Circle
When working with animations, it’s best to focus on the animation you’re currently implementing. Open ContentView.swift and comment out the .onAppear
closure. It should look like this:
.onAppear {
//DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
// withAnimation() {
// self.showSplash = false
// }
//}
}
This way, you won’t be distracted by the splash screen fading out to reveal the MapView
after X seconds. Don’t worry, you’ll uncomment that part when you’re done and ready to ship.
You can now focus on the animation. Start by opening SplashScreen.swift and, right below SplashScreen
‘s closing bracket, add a new struct called FuberU
:
struct FuberU: Shape {
var percent: Double
// 1
func path(in rect: CGRect) -> Path {
let end = percent * 360
var p = Path()
// 2
p.addArc(center: CGPoint(x: rect.size.width/2, y: rect.size.width/2),
radius: rect.size.width/2,
startAngle: Angle(degrees: 0),
endAngle: Angle(degrees: end),
clockwise: false)
return p
}
// 3
var animatableData: Double {
get { return percent }
set { percent = newValue }
}
}
Here’s what you’re doing with this code:
- Implementing
path(in:)
as required by theShape
protocol. - Using a path to draw an arc starting at 0 and ending at 360, i.e a full circle.
- Adding an extra property, so SwiftUI knows how to animate your shape.
In order to see your new type in action, you’ll set up some variables and an animation, then declare it on body
with some modifiers.
Start by adding these variables right before the body
element in the SplashScreen
struct:
@State var percent = 0.0
let uLineWidth: CGFloat = 5
You’ll use these variables when initiating and modifying FuberU
.
Then, add the following code after SplashScreen
‘s struct closing bracket:
extension SplashScreen {
var uAnimationDuration: Double { return 1.0 }
func handleAnimations() {
runAnimationPart1()
}
func runAnimationPart1() {
withAnimation(.easeIn(duration: uAnimationDuration)) {
percent = 1
}
}
}
handleAnimations()
will be the basis for all of the different parts of the splash screen’s complex animation. It’s based on “magic numbers”, which you can play around with and tweak to match your exact taste later.
Finally, add the following code inside body
, between the existing Text
and Spacer
elements.
FuberU(percent: percent)
.stroke(Color.white, lineWidth: uLineWidth)
.onAppear() {
self.handleAnimations()
}
.frame(width: 45, height: 45, alignment: .center)
Here, you add the new circle, which will eventually represent a part of the Fuber ‘U’, to the stack at a specific position. In addition, you call handleAnimations()
when the view appears.
Build and run your app:
You can see that something is happening, but it’s not exactly what you might expect. Your code is indeed drawing a circle, but only one time, and the circle’s border is way too thin. You want it to fill the entire circle. You’ll fix those problems right away.