Let’s start Swift UI

This is my personal memo written in October 2020.

This article was written under the following system environment:
- macOS Catalina Version 10.15
- Xcode Version 12.0

TL;DR,
I. Preparation: What needs for Swift UI Programming
II. Swift UI Basic Topic
III. Swift UI mechanism

I. Preparation: What needs for Swift UI Programming

A. Creating New Project

  1. Select iOS > App and press the “Next” button.

2. Set the following items and press the “Next” button.

  • Interface: SwiftUI
  • Life Cycle: UIKit App Delegate
  • Language: Swift

B. Change iOS Deployment Target to iOS 13.0

  1. Open “Projects” > “Build Settings” > “Combined”
  2. Change “iOS 14” to “iOS 13.0” in “‘Deployment’ > ‘iOS Deployment Target’”

C. Show the preview on “Canvas”

  1. Select “ContentView.swift”
  2. Press the “Resume” button, then show up “Canvas”.

D. Write code inside var body: some View { }

Write your code inside “var body: some View { … }” in “ContentView.swift”.

II. Swift UI Basic Topic

A. A “var body” needs only one “View” for one screen layout

“var body: some View { … }”(in the following, we call “var body”) needs to have only one “View”.
If two or more Views are set in “var body”, the preview canvas will be separated into two screens or more.

And also in case “var body” has no View, XCode will claim error.

B. Basic 3 ways Layout Views

  1. ZStack
    The View on top in Editor is drawn behind the View in Canvas.
    The top/bottom relationship is replaced by the back/front relationship.

2. VStack
VStack places the Views vertically.

3. HStack
HStack places the Views horizontally.

C. Everything is a View

In Swift UI, every layout part which is visible or invisible is View.

When you want to check the Swift UI default View, press the “Library” button to show up the “Views” icons.

Or, you can check the Views original definition in SwiftUI code.

The SwiftUI Views code will be shown up.

D. Modifier

“View” will be recalculated and replaced when using “Modifier” with some “View”

The dot chain method makes a connection “Modifier” with “View”.

Rectangle().foregroundColor(.red)

In the above example, foregroundColor(.red) is Modifier. And Rectangle() is View. The dot connect foregroundColor(.red) with Rectangle() .

The foregroundColor(.red)Modifier makes the View Rectangle() recalculated and replaced to show up the View on Canvas.

We can check which Modifier can be added.
1. Select some View and Command(⌘) + Mouse Click
2. Select “Show SwiftUI Inspector…” item.

3. Then select the “Add Modifier” text box.

Multiple modifiers can be connected.

E. Parent-Child Relationships

However, if we use Modifiers that have the same influence on the parent View and their Child View, the child Modifier overrides the influence of the parent Modifier.

.overlay() Modifier also makes the parent-child relationships of Views.

In the following case, the grandchild also is affected by “VStack” View’s Modifier impact.

F. 2 Types Views for Layout Behavior (Pull-In and Push-Out)

  1. Pull-In View
    - Text View
    - VStack
    - HStack
    …etc

2. Push-Out
- Rectangle View
- RoundRectangle View
- Circle View
…etc

G. Frame Modifier makes a new frame on View

Each view has its own frame.
View has a box image looked like the CSS box image.

1. “.border()” Modifier show up the frame’s border
2. “.frame()” Modifier can change own frame’s Width and Height
3. “.padding()” Modifier makes a new frame for View.
4. “.offset()” Modifier move the own View from the original frame position and make a new frame.

H. Your Definition View can be used in other View

The View which we set as View type, is easily available in other View’s bar body .

I. Change Views with DATA

Using @State var , it is easy to catch DATA change.

3. Swift UI mechanism

  • A. Where is “return”?
  • B. What’s happening inside “{…}”?
  • C. What is “some”?

The above questions can be explained by the following Swift language functions.
These functions are available in Swift5.1 or above.

  • A. Implicit return from single expressions
  • B. Function Builders
  • C. Opaque Result Type

A. Implicit return from single expressions

(Swift Evolution: SE-0255)

Earlier than Swift 5.1, when there is only one formula in Closure, the Closure’s “return” can be omitted.

That’s why the following Closure's “return” can be omitted in Swift 4.2 also.

let names = persons.map { return $0.name }

In Swift 5.1 or above versions, not only Closure but also normal Function and Computed Property can also omit “return”, when their formula is only one.

struct Triangle {    var base:Double = 3, height:Double = 4    var area: Double {        // Here is Computed Property's formula
// This "return" can be omitted
return base * height }
}

And “{…}” inbar body is Computed Property.

That’s why inside var body in Swift UI, it omits “return”.

B. Function Builders

  • Function Builders creates variable declarations and function calls from line-delimited elements.
  • @_functionBuilder is added to a function’s parameter, this function is changed to Function builder.
  1. Jump to the “VStack” definition in SwiftUI

2. The@ViewBuilder parameter named content is used in VStack

3. Additionally, check the @ViewBuilder definition in the same SwiftUI file.

And after struct ViewBuilder {...} statement, we can see someextention ViewBuilder{...} statements.

In these extention ViewBuilder{...} statements, these statements represent that ViewBulder changes Views as parameters to TupleView .

And these statements also means that @ViewBuilder parameter can handle more than 1 View and up to 10 Views.


Up to 10 Views, these similar extensions are set.

It means VStack handles only up to 10 Views.

import SwiftUIstruct III_B_ViewBuilder: View {
var body: some View {
VStack {
Text("1")
Text("2")
Text("3")
Text("4")
Text("5")
Text("6")
Text("7")
Text("8")
Text("9")
Text("10")
// If more than 10 View is added, XCode will appear error.
// Text("11")
}
}
}

If we use more than 10 Views, we can use Group View in VStack or other Views which appropriate@ViewBuilder parameters.

import SwiftUIstruct III_B_ViewBuilder: View {
var body: some View {
VStack {
Text("1")
Text("2")
Text("3")
Text("4")
Text("5")
Text("6")
Text("7")
Text("8")
Text("9")

Group {
Text("10")
Text("11")
Text("12")
Text("13")
}
}
}
}

We can eliminate the error by setting the number of elements treated as ViewVilder parameters to 10 or less.

Additionally, we can rewrite VStack formulas.

The abbreviated parts of VStack can be expressed as follows when written.

import SwiftUIstruct III_B_ViewBuilder2: View {
var body: some View {

VStack {
return ViewBuilder.buildBlock( Text("1"),
Text("2"),
Text("3"),
Text("4"),
Text("5"),
Text("6"),
Text("7"),
Text("8"),
Text("9"),
Group {
Text("10")
Text("11")
Text("12")
Text("13")
}
)
}
}
}

B’. Let’s try to create a new Function Builder and use it

  1. Create a new struct as Function Builder according to the syntax of the Function Builder.
@_functionBuilder public struct NumbersAdder {

public static func buildBlock(_ num01: Int) -> Int {
return num01
}
public static func buildBlock(_ num01: Int, _ num02: Int) -> Int {
return num01 + num02
}
public static func buildBlock(_ num01: Int, _ num02: Int, _ num03: Int) -> Int {
return num01 + num02 + num03
}
}

2. Create a new function. The function’s parameter is appropriated the above Function Builder.

func addNumbers(@NumbersAdder number: () -> Int) -> Int {
number()
}

3. Use addNumbers .

let sumNumbers = addNumbers {
1
2
3
}
print(sumNumbers)

C. Opaque Result Type

(Swift Evolution: SE-0244)

  • It’s like Generics.
  • some+ Protocol
  • some View means “Disclose exactly Type but some View means some Type which appropriate View Protocol”.
import SwiftUIstruct III_C_OpaqueResultType: View {    var bodyContent: some View = VStack {
Text("Today is Saturday")
Text("Tomorrow is Sunday")
}
var body: some View {
bodyContent
}
}
struct III_C_OpaqueResultType_Previews: PreviewProvider {
static var previews: some View {
III_C_OpaqueResultType()
}
}

We can set more concrete Types instead of “some View”.

--

--

iOS Developer, Front-end Developer

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