What’s new in SwiftUI (Xcode 12 Beta) – Everything you should know

Share on facebook
Share on twitter
Share on pinterest

At WWDC20, Apple introduced Xcode 12 coming with an updated version of the SwiftUI framework. This update provides SwiftUI developers with a huge amount of new features and concepts, enhanced workflow, and improved stability. This article summarizes all major updates getting shipped with Xcode 12. We will explore a reworked app hierarchy concept, new and improved views and modifiers, and many more new features.

Hint: The SwiftUI update we’re talking about in this tutorial gets shipped with the new Xcode 12 Beta. Check out this tutorial to learn where to download it and what else you should know about the new Xcode update. 

New app hierarchy concept 🔽💡

The first thing you notice when you create a new SwiftUI project in Xcode 12 is that besides the usual ContentView.swift file, another file is “YourProjectNameApp.swift” (By the way, if you’re wondering why there are multiple folders called “Shared”, “iOS” and “macOS”, check out this post). The code inside this file looks like this:

import SwiftUI

@main
struct YourProjectNameApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}


What is this all about? Well, with the new SwiftUI update, Apple introduced a reworked app hierarchy concept including new APIs like App and Scene

We will dedicate a whole article to talk about this in more detail, but let’s try to explain this new concept as concisely as possible.

As you already know, everything you see on the screen of your app is in some way defined by a View. The more complex the interface of your app gets the more nested Views you create resulting in less or more complex view hierarchies. 

Certain areas of visible Views can be divided into distinct regions. With the new SwiftUI update, we refer to those areas as Scenes. Scenes always consist of one or multiple Views and there are multiple types of Scenes, like WindowGroup or DocumentGroup


All Scenes together form the entire content for our App. An App itself contains Scenes which concludes in the following hierarchy structure of any SwiftUI app.


With this knowledge, you should grasp the rough concept when looking at the default code in your YourProjectApp.swift file. The highest piece in the hierarchy is the App which returns Scenes, which in turn return Views.


Of course, there is much more to know about this, so make sure you read our related article about this concept. What’s cool to know at this point is that with this new concept apps can be written using 100% SwiftUI and furthermore that these apps can be easily constructed for running on multiple platforms like iOS, iPadOS, and macOS.

LazyStacks, Outlines, and Grids 📑🖼

The new SwiftUI update provides us with many new features regarding stacks and lists. Supposed you want to create a long, scrollable collection of elements (imagine something like the Instagram feed), you need to wrap those elements into a VStack embedded into a ScrollView. 

ScrollView {
            VStack {
                //View 1, view 2 etc.
            }
        }

However, the problem with this is that all views inside the VStack get initialized at once regardless of whether they are currently shown on screen. Depending on the number of views inside the stack, this could lead to performance issues.


Apple now remedies this by introducing LazyVStacks and LazyHStacks. By using these, we make sure that the content inside the VStack or HStack only gets loaded once they will be visible on the screen.

ScrollView {
            LazyVStack {
                //View 1, view 2 etc.
            }
        }

Furthermore, Apple equipped Lists with so-called outlines. Supposed you have a data model which allows children instances, for instance, something like this:

struct Film: Identifiable {
    let id = UUID()
    var name: String
    var parts: [Film]?
}

And a corresponding data set containing sub-instances:

let myFilmCollection = [
    Film(name: "Pulp Fiction"),
    Film(name: "Interstellar"),
    Film(name: "Lord of the Rings", parts: [
        Film(name: "The Fellowship of the Ring"),
        Film(name: "The Two Towers"),
        Film(name: "The Return of the King")
    ]),
    Film(name: "The Godfather")
]

And you want to display the data by grouping the children instances into an outline, you can pass your data into the list and indicate the children elements by providing SwiftUI with the corresponding property key path of your data model. 

List(myFilmCollection, children: \.parts) { movie in
            Text(movie.name)
        }

How the outline is presented depends on the device the app runs on and the .listStyle you apply to the List. On iOS and with no custom .listStyle applied the resulting List looks something like this: 



Finally, with the new update, we have a proper alternative to UICollectionView we know from the UIKit framework: Grid views. Those Grids are super easy to implement. Just embed a LazyVGrid or LazyHGrid (yes, they are lazy by default) into a ScrollView. Specify the number and appearance of the rows/columns by passing a GridItem collection. 

struct ContentView: View {
    
    var columns = [
        GridItem(spacing: 5),
        GridItem(spacing: 10),
        GridItem(spacing: 5)
    ]
    
    var body: some View {
        ScrollView {
            LazyVGrid(columns: columns, spacing: 100) {
                
            }
        }
    }
}

Inside the Grid, you can iterate through a specific data set and return a cell for every element inside this data set, like do it with Lists.

ScrollView {
            LazyVGrid(columns: columns, spacing: 100) {
                ForEach(0 ..< 100) { entry in
                    MyCell()
                }
            }
        }

This is how such a Grid looks like in action:


More views, modifiers and customization options 🆕

Apple also introduced many more views, modifiers and customization options for existing modifiers and views. You already got to know the new Grid view. Another cool new view is the ProgressView. By inserting a plain ProgressView instance we get a spinning activity indicator. When passing a value to it, we get a linear progress bar by default.

struct MyProgressView: View {
    
    @State var progress = 0.4
    
    var body: some View {
        ProgressView(value: progress, total: 1.0)
            .padding(10)
    }
}


Another new feature is the Label view. A Label consists of a String and an appended Image and its appearance depends on the context where the label is placed in. For example, let’s create a List with two sections containing several Label views.

NavigationView {
            List {
                Section(header: Text("Drama")) {
                    Label("The Godfather", systemImage: "film")
                    Label("The Shawshank Redemption", systemImage: "film")
                    Label("Green Mile", systemImage: "film")
                }
                Section(header: Text("Comedy")) {
                    Label("Bruce Almighty", systemImage: "film")
                    Label("Night at the Museum", systemImage: "film")
                    Label("Men in Black", systemImage: "film")
                    Label("Jumanji", systemImage: "film")
                }
            }
                .navigationTitle(Text("My Film Collection"))
        }

This is how the resulting preview looks like. 


Note: In specific situations, for example in plain lists, Label views seem to have weird behavior, as you see in the image above (I’m currently not certain if this is a bug in Xcode 12 beta). However, we can change this when applying a certain .listStyle, for example to SidebarListStyle which is new this year and provides us this beautiful layout:

List {
                //...
            }
                .listStyle(SidebarListStyle())
                //...
List {
                //...
            }
                .listStyle(SidebarListStyle())
                //...


Another cool new modifier is .listItemTint which we can apply to views inside a list or to whole sections like this:

List {
                Section(header: Text("Drama")) {
                    //...
                    Label("Green Mile", systemImage: "film")
                        .listItemTint(.gray)
                }
                Section(header: Text("Comedy")) {
                    //...
                }
                    .listItemTint(.gray)
            }
                .listStyle(SidebarListStyle())
//...

Finally, we can also customize the tint color of controls like Toggles like this: 

Toggle("Show favorites only", isOn: $isOn)
                    .toggleStyle(SwitchToggleStyle(tint: .blue))


There are several more views, modifiers and customization options to discover. This is beyond the scope of this article and will be discussed in separate tutorials.

Updated data flow concept 🌊

Apple has also reworked the data flow concept in SwiftUI and especially adapted it to the new App hierarchy we mentioned above and also introduced new property wrappers like @StateObject or @SceneStorage.

This would also go beyond the scope of this article and we will publish a dedicated tutorial on this topic in the near future. 

Good to know is that the data flow structure of your existing SwiftUI apps can be adopted without any further adjustments.

Enhanced system integration 🚀

Finally, let’s talk about to enhanced system integration Apple provides the SwiftUI framework with. 

On the one hand, there are features like Links that you can insert into your SwiftUI view that automatically opens a specified destination, for example, a URL in your browser.

Link(destination: myURL) {
                    Label("IMDB List", systemImage: "star")
                }



On the other hand, third frameworks such as AVKit or SceneKit now provide possibilities to use their functionality directly in SwiftUI apps without having to take the detour via UIHostingController as it was often the case before.

Conclusion 🎊

So you see that SwiftUI has become even more powerful. With more views, more functional modifiers and customization options, a revised app hierarchy concept, and advanced system integration, it is now even easier to write powerful apps with 100% SwiftUI.

As I said, we will write separate tutorials on many topics, in which we will go into more detail. Make sure you subscribe to our newsletter so you don’t miss anything (No spam, I promise!).

Leave a Reply

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

small_c_popup.png

Covid-19 Forces you into quarantine?

Start Mastering swiftUI Today save your 33% discount

small_c_popup.png

Are you ready for a new era of iOS development?

Start learning swiftUI today - download our free e-book