CS193p Notes - Lecture 3: Reactive UI + Protocols + Layout
Tags: ios, swift
Published: 2020-07-26 16:35:24

- 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`

Reactive

- `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.

```swift
protocol Greatness {
    func isGreaterThan(other: Self) -> Bool
}

extension Array where Element: Greatness {
    var greatest: Element {
        // for-loop through all the elements
        // which (inside this extension) we know each implementes the Greatness protocol
        // and figure out which one is greatest by calling isGreaterThan(other:) on them
        return the greatest by calling isGreaterThan on each Element
    }
}
```

- `Self` means that type comes from the thing that is implementing that protocol.

---

### Layout ([49:57](https://youtu.be/SIYdYpPXil4?t=2997))

- 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)

```swift
HStack {
    Text("Important").layoutPriority(100)
    Image(systemName: "arrow.up") // default layout priority is 0
    Text("Unimportant")
}
```

- 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](https://youtu.be/SIYdYpPXil4?t=4324))

```swift
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.

[@RealLankinen](https://twitter.com/reallankinen)

- [Notes 1](https://dev.to/lankinen/cs193p-notes-lecture-1-course-logistics-and-introduction-to-swiftui-44ap)
- [Notes 2](https://dev.to/lankinen/cs193p-notes-lecture-2-mvvm-and-the-swift-type-system-406f)
- [**Notes 3**](https://dev.to/lankinen/cs193p-notes-lecture-3-reactive-ui-protocols-layout-5g8a)
- [Notes 4](https://dev.to/lankinen/cs193p-notes-lecture-4-grid-enum-optionals-4noj)
- [Notes 5](https://dev.to/lankinen/cs193p-notes-lecture-5-viewbuilder-shape-viewmodifier-fgh)
- [Notes 6](https://dev.to/lankinen/cs193p-notes-lecture-6-animation-1a8f)
- [Notes 7](https://dev.to/lankinen/cs193p-notes-lecture-7-multithreading-emojiart-2ak3)
- [Notes 8](https://dev.to/lankinen/cs193p-notes-lecture-8-gestures-json-1f3m)
- [Notes 9](https://dev.to/lankinen/cs193p-notes-lecture-9-data-flow-26e)
- [Notes 10](https://dev.to/lankinen/cs193p-notes-lecture-10-navigation-textfield-3ei9)
- [Notes 11](https://dev.to/lankinen/cs193p-notes-lecture-11-picker-2hgh)
- [Notes 12](https://dev.to/lankinen/cs193p-notes-lecture-12-core-data-eci)
- [Notes 13](https://dev.to/lankinen/cs193p-notes-lecture-13-persistence-2jeh)
- [Notes 14](https://dev.to/lankinen/cs193p-notes-lecture-14-uikit-integration-1p7m)

[Originally published here](https://www.notion.so/lankinen/CS193p-2020-iOS-development-course-from-Stanford-81c094238e9d471bbf059ea8d83b3e15)