Creating Skeleton Loaders in SwiftUI
In our apps we often populate lists with content that is fetched from elsewhere. Some server or service somewhere on the internet.
The connection quality of the device on the go is different all the time. Ranging from perfect WIFI at home to slow 3G during the commute.
Our users might see the following
An empty list of categories.
Depending on how fast the connection is, or how performant the data source, the list will get filled eventually. Quickly, slowly or just in time.
The longer it takes the more likely the user is to think something went wrong.
Are there no categories available? Did something break?
Some try to solve the issue with a loading indicator. There is a nicer way.
Skeleton loaders to the rescue!
Because Skeleton loaders represent the final content shapes we need to know how the loaded list of categories looks like.
All the screenshots were taken using Market Cap Game. Market Cap Game uses Skeleton loaders.
Using the SwiftUI List
container our code looks like
Turning this into using Skeleton loaders is quite simple. The loading step between empty list and the populated list can look as follows
With the awesome library SkeletonUI the above is achieved with
The List
container was replaced with SkeletonList
container. We pass a quantity
because the amount of categories
is not known yet. The quantity
sets how many skeleton bars we need.
Because item
became an Optional we have to make a few adjustments.
Our actual values are rendered as soon as an item
in categories
is present.
We could even split the single broad line per item into two lines with a different width. Category name and the description.
We add the following via chaining after .shape
.multiline(lines: 2, scales: [0: 0.5, 1: 0.8], spacing: 20)
We use the one that closest represent the final content shapes by playing with all the shapes SkeletonUI has to offer.
Our app now behaves as follows
To wrap things up using Skeleton loading animations in SwiftUI is a lot easier than achieving the same it with our old friend the Interface Builder.