-
Notifications
You must be signed in to change notification settings - Fork 5
Swift UI for Fluter Developers
Swift UI is a declarative UI toolkit. Therefore, Swift UI shares many characteristics with Flutter. However, Swift UI also includes a number of details that will be foreign to a Flutter developer. Such differences include syntax, paradigm, and available resources.
This guide provides a rapid introduction to Swift UI details that may not be immediately evident to a Flutter developer.
Swift UI doesn't use Widget
subclasses to declare pieces of a UI. Instead, Swift UI uses View
subclasses to declare pieces of a UI. And technically they aren't "subclasses" - they're struct
s that conform to the View
protocol. But you can think of Swift UI View
s as the equivalent of Flutter's Widget
s.
struct MyView: View {
// TODO: implement the View, AKA widget.
}
Instead of defining a build()
method within a Widget
, Swift UI developers define a body
property within a View
.
struct MyView: View {
var body: some View {
// TODO: build the body of this View, AKA the build() of the widget.
}
}
In Flutter, Widget
s are typically composed within other Widget
s by using a property called child
or children
.
ContextMenu(
children: [
Text("Cut"),
Text("Copy"),
Text("Paste"),
if (isSymbol)
Text("Jump to Definition"),
],
);
In Swift UI, a special language feature is used to make it seem like no property is used at all to compose View
s within View
s. Swift UI uses trailing closures, which are expected to produce one or more View
s. These closures are called ViewBuilder
s.
ContextMenu() {
Text("Cut")
Text("Copy")
Text("Paste")
if isSymbol {
Text("Jump to Definition")
}
}
In the above example, we're providing children to the ContextMenu
. The closure {}
, which follows ContextMenu()
, is actually an argument that's passed into ContextMenu()
.
The ability to pass a closure as an argument, while declaring the closure AFTER the invocation, is a Swift language feature. It's called Escaping Closures
Sometimes Swift UI code composes View
s within View
s in a manner that's very similar to Flutter.
ContextMenu() {
Text("Cut")
Text("Copy")
Text("Paste")
if isSymbol {
Text("Jump to Definition")
}
}
However, most of the time, Swift UI code uses a different approach to compose View
s, as well as configuration settings. This other approach is called "modifier methods". Modifier methods are methods called on a View
.
content
.font(.caption2)
.padding(10)
.overlay(
RoundedRectangle(cornerRadius: 15)
.stroke(lineWidth: 1)
)
.foregroundColor(Color.blue)
For the most part, modifier methods are little more than a stylistic paradigm choice. They accomplish the same or similar results as View
composition, but with a different order of operations.
Let's demonstrate the interchangeable nature of View
composition and modifier methods borrowing an example
Consider a situation where we'd like to implement the concept of a "featured label".
Here's a featured label implemented with View
composition:
struct FeaturedLabel: View {
var text: String
var body: some View {
HStack {
Image(systemName: "star")
Text(text)
}
.foregroundColor(.orange)
.font(.headline)
}
}
struct ContentView: View {
var body: some View {
VStack {
// View-based version:
FeaturedLabel(text: "Hello, world!")
}
}
}
Here's a featured label implemented as a modifier method:
extension View {
func featured() -> some View {
HStack {
Image(systemName: "star")
self
}
.foregroundColor(.orange)
.font(.headline)
}
}
struct ContentView: View {
var body: some View {
VStack {
// Modifier-based version:
Text("Hello, world!").featured()
}
}
}
As you can see, the same result is achieved in both cases.
There may be some use-cases which are easier to implement with modifier methods, but in general these two approaches differ only in stylistic preference.
Many Swift UI examples include string references to system icons, e.g., "tray.and.arrow.down.fill"
. You might wonder where you can find a list of all such icons.
Swift UI calls these icons "symbols" and there is no simple web directory of available symbols. Instead, you must download the SF Symbols app for Mac, which browses all available symbols.