CS193p Notes — Lecture 3: Reactive UI + Protocols + Layout

  • ViewModel is never calling View but View calls ViewModel — One ViewModel can be used by many Views and that is why it’s a class
  • Holding option and clicking a variable name allows to do all kind of things like rename.
  • mutating keyword is used front of func when it's changing self
  • in struct EmojiMemoryGameView: View { View is called protocol (constrains and gains). The idea is that we gain something (functions) from using it but it also contrains us to do something like have var body: some View


  • ObservableObject is constraint and gain that gives a class (ViewModel) ability to follow changes. Every time something changes it updates the UI.
  • objectWillChange.send() is can be added to functions where some object will change.
  • It’s more common to add @Published property wrapper front of the variables that will change because that way you don't forget to add objectWillChange.send() to some position.
  • Behind the scenes it checks that every time that variable is changes it calls objectWillChange.send()
  • @ObservedObject is added front of ModelView in View class to redraw it every time the ModelView changes.
  • protocol is like stuct/class that can contain vars and functions but it doesn't had implementation to them.
  • Classes and structs can use protocol following way class Car: Vehicle It's possible to implement multiple protocols by separating them with commas.
  • Protocols can also inherit other protocols protocol Vehicle: Moveable ...
  • protocol offers constrains and gains
  • The idea in protocols is that multiple structs/classes can use it and then if it’s extended all of them get the new feature
  • extension is used to add new functionalities to structs, classes, protocols
  • Protocols are useful because they say what the types (structs/classes/other protocols) are capable of and also demand certain behavior.
protocol Greatness {
func isGreaterThan(other: Self) -> Bool
  • Self means that type comes from the thing that is implementing that protocol.

Layout (49:57)

  • HStack and VStack
  • Offers space to its “least flexible” subviews first
  • Image: “inflexible”
  • Text: “slightly more flexible”
  • RoudedRectangle: “flexible”
  • Defaults work a little bit differently in different devices and that is why we should keep them and not put specific numbers because those probably doesn’t work as many device
  • Spacer takes the space given and draws nothing
  • Divider Draws line (horizontal or vertical depending the stack)
HStack {
Image(systemName: "arrow.up") // default layout priority is 0
  • Important text takes the space it wants
  • Then image takes the space it wants
  • Finally Unimportant text takes the remaining space

Demo (1:12:04)

struct CardView: View {
GeometryReader { geometry in
ZStack {
if self.card.isFaceUp {
RoundedRectangle(cornerRadius: 10.0).fill(Color.white)
RoundedRectangle(cornerRadius: 10.0).stroke(lineWidth: 3)
} else {
RoundedRectangle(cornerRadius: 10.0).fill()
.font(Font.system(size: min(geometry.size.width, geometry.size.height) * 0.75))

It’s common to move the numbers to a “control panel”. In one place it’s easy to modify them and the main code becomes cleaner.


Lecture 1
Lecture 2
Lecture 3
Lecture 4
Lecture 5
Lecture 6
Lecture 7
Lecture 8
Lecture 9
Lecture 10
Lecture 11
Lecture 12
Lecture 13
Lecture 14

Originally published: https://www.notion.so/lankinen/Lecture-3-Reactive-UI-Protocols-Layout-601ab99e83794e168c45b8354a3faec4