WWDC20: Advancements in SwiftUI

Ryan Donovan
Oct 28, 2020 · 7 min read
Image for post
Image for post
A new App Lifecycle, new View Types, Lazy Loading, and more

Among numerous advancements in iOS development brought to us in WWDC20 are a number of updates, enhancements, and demonstrations of an overall continued effort to build out the robustness of SwiftUI, furthering its viability as the preferred method of UI development in iOS.

In order to learn as much as possible about these updates to SwiftUI, we built a sample Cities app, with the objectives being to explore the new app lifecycle, new View types, modifiers, property wrappers, and any other general improvements we found along the way.

The SwiftUI App Lifecycle

Upon creating a new project in Xcode, with the SwiftUIApp Life Cycle selected, you’ll notice your project is pre-packaged with a new Swift file, named to match your project. This file effectively replaces AppDelegate and SceneDelegate, and is all that is needed to startup and run your app. The code will look something like this:

This ContentView can be any View type you want your app to begin with. We’re going to create a TabView to allow our user access to the three different views that comprise our Cities app: CityHomeView, CityGridView, and CityListView.

We are going to modify each tab item using the tabItem() modifier. In addition to the updates to SwiftUI, WWDC20 brought us some advancements to SF Symbols. SF Symbols 2 offers over 750 new Symbols, multicolor Symbols, localization enhancements, and better optical alignment control with the ability to customize leading and trailing attributes. For each tab item, we’ll provide a SF Symbol Image and associated text.

The new SwiftUI App Lifecycle has dramatically simplified the process of creating and starting up your app, allowing you, the developer, to focus more on the fun stuff, and less on the setup.

Lazy Stacks

SwiftUI in iOS 14 offers new View types that load lazily. VStack and HStack now have lazy counterparts, LazyVStack and LazyHStack, to load our content lazily on demand.

When a VStack or HStackis created the system also creates all of their subviews. On the other hand, when a LazyVStack or LazyHStack is created the system creates each subview only when it is needed to render on screen. These lazy stacks match the performance benefits of UITableView and UICollectionView from UIKit.

The benefit of lazy stacks is made apparent through large data sets. In fact, we recommend not using lazy stacks unless you are dealing with a large data set. Let’s walk through some examples.

The third tab in our app, CityListView shows a long list of city names. A button in the navigation bar toggles between displaying the list using a LazyVStack and a regular VStack using a binding called isLazy. Here’s how it looks:

We started off with a list of approximately 26,500 city names from simplemaps.com. Running on an iPhone 11 Pro the lazy stack loads instantly and is able to immediately scroll smoothly through thousands of names. Unfortunately, scrolling quickly down the list eventually causes the app to run out of memory and crash!

Will VStack do better? Tapping the toggle button switches to the regular stack and immediately pauses the UI. After a few seconds the app crashes. VStack attempts to render the view with all 26,500 city names up front and unfortunately it doesn’t succeed.

Whichever way we go it appears that 26,500 names pushes the system too far. After dividing the list of names in half three times down to about 3,300 we are finally able to render the regular VStack. With about 3,300 names the LazyVStack is fully capable of loading instantly and scrolling smoothly through the entire list. On the other hand, regular VStack takes a couple seconds to render the view after tapping the toggle button. Once loaded the VStack scrolls smoothly through all of the names.

We also tried scrolling through the 26,500 city names using List which was already available before WWDC20.

Using List we are able to successfully scroll through all of the names without crashing. However, framerate was noticeably bad. If you need to show an enormous number of rows in a table layout then List might be preferable to using either a LazyVStack or VStack.

Lazy Grids

SwiftUI and iOS 14 also offer us LazyVGrid and LazyHGrid for grid layouts. The addition of these views is an exciting enhancement, as they serve as a flexible replacement for UIKit’s UICollectionView, a commonly used view type which SwiftUI was previously lacking.

LazyVGrid and LazyHGrid are container views that arrange their child views in a grid, growing vertically and horizontally, respectively, and only creating items as needed.

On initialization, you can provide an array of GridItem's, which essentially describe how the grid should lay out. In our example, we’ll use GridItem(.adaptive(minimum: 180)), meaning we want our grid to fit as many items as possible in each row, so long as that item has a minimum size of 180 points. We’ll call our array of GridItem's columns, since we are going to use a LazyVGrid.

We could have also used GridItem(.flexible()) if we wanted to specify how many columns to use, or GridItem(.fixed()) to explicitly set the size of the item.

Once we have set our columns, we can create our LazyVGrid using those columns:

And the result:

Image for post
Image for post

What if we wanted a horizontal grid? It’s really quite easy. We just need to set our GridItem array to account for rows, rather than columns. I could use the same GridItem(.adaptive(minimum: 180)) and ensure we have exactly 180 points for each item, but for variation’s sake, let’s specify that we want exactly 4 rows, with .flexible(), and give each one a minimum height of 200:

Image for post
Image for post

MapKit

SwiftUI in iOS 14 now offers us the ability to easily show and display MapKit views in our SwiftUI views.

We just need a @State variable to track an MKCoordinateRegion that will be used for the center of our map.

So, we’ll create a CityDetailView, showing a map of the provided city, using that city’s coordinates, MapKit, and SwiftUI’s Map view.

Once we have a City, we can set our @State variable to track that City’s coordinates in an MKCoordinateRegion.

And in our view, we can just display that region in a map as such:

The result:

Image for post
Image for post
Boston Image Creator: Sean Pavone Copyright: Sean Pavone 2017 _Langan_ https://www.langan.com/locations/boston-massachusetts

Other New View Types

Label

Label is a new UI component to combine an icon with text. The simplest form of a Label can be created using a title and the name of an image. We’ll do so, using an SF Symbol:

The icon will size accordingly with the font of the text in the label, and will scale for dynamic type. iOS 14 also introduces the ability to change color for SF Symbols, so we can apply view modifiers to this label and consequentially change the color of both the icon and the text.

Image for post
Image for post
Label in SwiftUI

ColorPicker

SwiftUI in iOS 14 also offers a new ColorPicker. We just need to track a color property as a @State variable, and we can set our Label’s color to match that of the ColorPicker.

Image for post
Image for post
ColorPicker in SwiftUI

Modal Presentation

SwiftUI’s new fullScreenCover view modifier allows us to present another view modally, covering as much of the screen as possible. Let’s present a larger version of our image on CityDetailView when the user taps the image.

We just need to add a @State variable to track when the modal view has presented, and to add the .fullScreenCover modifier to our image. Our fullScreenCover will track the binding to our @State variable, and we will supply it with View content.

In our newly created CityImageModalView, we just need an environment property to allow the view to dismiss itself. In the View, we’ll add a Button to dismiss.

Image for post
Image for post

Conclusion

SwiftUI continues to develop, expand, and advance its viability as the preferred method of UI development for iOS. The addition of new view types makes it easier to replicate more and more UIKit views, while its sleekness, flexibility, and intuitiveness, whether it be through the new SwiftUI App Lifecycle or view definition, enhance the simplicity and efficiency of development. Look for SwiftUI to continue to grow in the future, and in the meantime, check out these latest advancements for yourself!

Image for post
Image for post
Image for post
Image for post

CapTech Corner

A place to find the best technical expertise from our own CapTechers

Ryan Donovan

Written by

Mobile Developer @ CapTech with a special focus in iOS Development

CapTech Corner

We are a team of master builders, creators, and problem solvers who unite diverse skills and perspectives to transform how data, systems, and ingenuity enable organizations to advance what’s possible in a changing world. Here you’ll find the latest expertise from our people.

Ryan Donovan

Written by

Mobile Developer @ CapTech with a special focus in iOS Development

CapTech Corner

We are a team of master builders, creators, and problem solvers who unite diverse skills and perspectives to transform how data, systems, and ingenuity enable organizations to advance what’s possible in a changing world. Here you’ll find the latest expertise from our people.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store