CS193p Notes - Lecture 5: ViewBuilder + Shape + ViewModifier
Tags: ios, swift
Published: 2020-07-26 16:36:42

### Access control

- `private` doesn't allow anyone outside the struct/class access it
- `private(set)` means that setting is private but reading is not meaning that anyone can read it

### ViewBuilder ([12:05)](https://youtu.be/oDKDGCRdSHc?t=725)

`@ViewBuilder` can be added to any function that returns a view. If there is a list of views it combines them into one.

"The contents of a `@ViewBuilder` is a list of Views. No need to type `return`. Cannot use `var`s.

```swift
@ViewBuilder
func front(of card: Card) -> some View {
  RoundedRectangle(cornerRadius: 10)
  RoundedRectangle(cornerRadius: 10).stroke()
  Text(card.content)
}
```

### Shape ([20:22](https://youtu.be/oDKDGCRdSHc?t=1222))

`CG` = Core Graphics

```swift
import SwiftUI

struct Pie: Shape {
  var startAngle: Angle
  var endAngle: Angle
  var clockwise: Bool = false

  func path(in rect: CGRect) -> Path {
    let center = CGPoint(x: react.midX, y: react.midY)
    let radius = min(rect.width, rect.height) / 2
    let start = CGPoint(
      x: center.x + radius * cos(CGFloat(startAngle.radians)),
      y: center.y + radius * sin(CGFloat(startAngle.radians))
    )
    
    var p = Path()
    p.move(to: center)
    p.addLine(to: start)
    p.addArc(
      center: center,
      radius: radius,
      startAngle: startAngle,
      endAngle: endAngle,
      clockwise: clockwise
    )
    p.addLine(to: center)
    return p
}
```

- 0 degrees is to right
- 0x0 is in left top corner and increases by going down and right

### ViewModifier ([41:54](https://youtu.be/oDKDGCRdSHc?t=2514))

- There are two things that can be animated: shapes and views.
- Animating views happens in ViewModifier
- Modifier can for example make any view to look like a card, cardify

```swift
Text("Ghost").modifier(Cardify(isFaceUp: true))

struct Cardify: ViewModifier {
  var isFaceUp: Bool
  func body(content: Content) -> some View {
    ZStack {
      if isFaceUp {
        RoundedRectangle(cornerRadius: 10).fill(Color.white)
        RoundedRectangle(cornerRadius: 10).stroke()
        content
      } else {
        RoundedRectangle(cornerRadius: 10)
      }
    }
  }
}
```

```swift
Text("Ghost").cardify(isFaceUp: true)

extension View {
  func cardify(isFaceUp: Bool) -> some View {
    return self.modifier(Cardify(isFaceUp: isFaceUp))
  }
}
```

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