5:35 RangeReplaceableCollection
因為 Collection 是 immutable,所以改成 RangeReplaceableCollection
6:16 subscripting
cards[card].isFaceUp = true
If no card with the card.id exists in cards, then this does nothing.
8:51 Color / UIColor / CGColor
Demo code at cs193p.stanford.edu
Architecture
MVVM - use ViewModel to bind the view to model
protocol Identifiable
Struct's mutating function
behide protcol ObserableObject
type Enum
02:56 build a ViewModel
Building Layouts with Stack Views
If your layout has one dominant view that defines the size of the layout, use the overlay(_:alignment:) or background(_:alignment:) view modifier on that view.
If you want the final view size to come from an aggregation of all the contained views, use a ZStack.
Making Fine Adjustments to a View’s Position
the offset(x:y:) modifier uses the parameters of x and y to represent a relative location within the view’s coordinate space.
ZStack 沒有指定 alignment,所以 Image 會在正中間(80,80)。 .offset(x: 40.0, y: -40.0) 加上這個偏移的話,就會坐落在第一象限。
26:18
a lot of people when they first started learning SwiftUI,
they think, "oh, that makes this writeable somehow, that now this View is mutable. It's got this variable to be writable."
But that's not true. This View is still immutbale.
It just turn this variable instead of really being a Boolean, it's actually a pointer to some Bollean somewhere else, somewhere in memory.
And that's where the value can change.
But this pointer does not change. It's always pointing to that same little space over there.
45:23 如果是寫這樣的話,點擊 🚆 會有兩個都被響應。