And I need a title there, not body text, and…”Got it.
You want to modify the default look and feel.
So how do we do that?Modifiers.
Yeah, I set up that one.
But it’s the term Apple uses and it fits, so we’ll stick with it.
Technically speaking, a modifier is an operator on a view… that returns another view….
which can be modified, ad infinitum (Or until you run out of memory ????).
From a practical standpoint, all you’re doing is using SwiftUI’s views and operators to describe the interface to SwiftUI, in almost exactly the same terms you’d use to describe the interface to another developer.
“I want my disclaimer text there, use the footnote font and size, and make it the secondary color so it works with dark mode.
”That’s one interface element with two modifiers.
Text("Your mileage my vary.
secondary)Describe the above interface to SwiftUI, and it does the rest, laying out the text with padding and spacing appropriate to the font size and the device your app is running on.
It automatically takes care of dynamic text and accessibility font sizes.
It automatically swaps the color so it looks correct in both light mode and dark mode.
It supports internationalization and text direction.
In short, it does its best to manage the fussy little details, and it does it on each and every element and part of your interface.
This frees you, the developer, to focus on your app’s features, business logic, and data.
Speaking of which…What About Our Data?Most apps are about data.
Sometimes the data is built into the app, as shown in our disclaimer example above, but usually, our data comes from an external source, a database, an API, or sometimes even from information directly entered into the app.
When we define a user interface element in SwiftUI, we also tell that element where to find the data it needs.
Sometimes that information is static, like the string in the text view shown above.
And sometimes that information is driven by our data.
In the following example, we’ve modified our list view to use the data that’s passed to it when it’s initialized elsewhere in the app.
The first parameter to list tells it exactly where to find its data.
List will then pull each element from the array and pass it into the closure, which in turn uses it to build and return a view that displays that element.
All of this happens with no data sources or delegates needed.
The above code could be a complete, working screen in your app.
Dynamic DataSometimes our information is dynamic, subject to change, and our interface should adjust accordingly.
The above implementation is practically identical to the first, but with a major difference, the @Binding property wrapper added to our list variable.
Binding tells SwiftUI to watch for changes to the list array.
Should its owner update the array’s contents, they’ll notify us and our list view will update and render itself — automatically.
You should note that List is an extremely smart little view.
Should the owner of the list insert an item and delete another, on learning of a change List will scan the updated list, compare it to the previous list, and then generate the proper insertion and deletion animations for you.
Also, note that we’re also now passing in the title we want in the navigation bar.
The title variable is also bound, so whenever that bit of data changes, our titlebar will automatically update to match.
Binding is just one of the ways you manage and maintain your application’s state in SwiftUI.
A full discussion of all of those is beyond the scope of this article, so stay tuned.
Under the HoodSo, you declare your interface and you point SwiftUI to your data… and SwiftUI does the rest.
Each View, the state of its modifiers, and its data is combined and aggressively reduced down to a set of layout and rendering commands.
The result is then presented to the user.
SwiftUI then waits for changes to the data.
Should they occur, SwiftUI walks through the affected views and builds a new layout tree, compares any changes it finds against the current tree, and then renders the portions of the view that need updating.
This makes SwiftUI blazingly fast compared to UIKit.
In fact, most of the view and animation rendering is done directly by Metal.
Animations?Yep, it’s easy to do animation in SwiftUI.
In fact, determining what animations may be needed for view state transitions is built directly into the tree comparison process.
Some animations, like List insertion and deletion and those pertaining to view modifier state changes, are built directly into the system.
And all of them can be modified if needed.
Completion BlockSo that’s it.
Hopefully, you now understand what Apple means when it says that SwiftUI is a new, declarative programming framework for constructing user interfaces on iOS and other Apple platforms.
And that the amazing modifier [sic] is well earned.
There’s much, much more to talk about, and I hope to get the state article out soon.
In the meantime, and if you haven’t already done so, you might check out my article on Best Practices in SwiftUI Composition.
As always, leave any questions or comments below, and I’ll do my best to answer them, either directly or in a future article.