< >
이 아니라 associated type
키워드를 통해 선언한다protocol Identifiable {
associatedtype ID: Hashable
var id: ID { get }
}
View
를 리턴하는 함수를 ViewBuilder
로 만들어준다 ViewBuilder
를 만듦!init
메서드가 필요?! 그냥 변수 선언 시에 붙여도 되긴 했음....// 인자
init(items: [Item], aspectRatio: CGFloat, @ViewBuilder content: @escaping (Item) -> ItemView) {
...
}
// 함수
@ViewBuilder
func someViewBuider() -> some View { }
init
을 통해 인자로 함수를 받을 때, 인자는 기본적으로 value type
이므로 해당 함수가 init
밖에서 쓰인다면 메모리 할당을 통해 힙에 저장해야 하기 때문에 escaping
으로 표기해줘야 함struct AspectVGrid<Item, ItemView>: View where ItemView: View, Item: Identifiable{
...
let content: (Item) -> ItemView
init(items: [Item], aspectRatio: CGFloat, @ViewBuilder content: @escaping (Item) -> ItemView) {
...
self.content = content
}
var body: some View {
GeometryReader { geometry in
VStack {
...
LazyVGrid(columns: [adaptiveGridItem(width: width)], spacing: 0) {
ForEach(items) { item in
content(item).aspectRatio(aspectRatio, contentMode: .fit) // 여기서 content 클로저가 이용됨
}
}
...
}
}
}
}
Path 구조체
는 이차원 그림을 그리는 데 필요한 다양한 함수를 갖고 있다!0도
가 시계 시침이 3시
를 가리키는 시점부터 시작하므로 통상적으로 생각하는 0도
가 12시
부터 시작하는 방식으로 각도를 구하려면 -90도
를 해주면 됨
Pie(startAngle: Angle(degrees: 0 - 90), endAngle: Angle(degrees: 110 - 90))
(0,0) 좌표
가 우리가 통상적으로 생각하는 좌측 하단이 아니라 좌측 상단
즉, 좌표계가 뒤집혀 있음!
0 -------------- x
|
|
|
|
|
y
struct Pie: Shape {
var startAngle: Angle
var endAngle: Angle
var clockwise = false
func path(in rect: CGRect) -> Path {
var p = Path()
let center = CGPoint(x: rect.midX, y: rect.midY)
let radius = min(rect.width, rect.height) / 2
let start = CGPoint(
x: center.x + radius * CGFloat(cos(startAngle.radians)),
y: center.y + radius * CGFloat(sin(startAngle.radians))
)
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
}
}
Path 구조체
를 거의 마지막에 배웠는데 오랜만에 보는 삼각함수...나중에 다시 한 번 찾아봐야할 것 같다...LectureMemorizeApp.swift
파일의 LectureMemorizeApp
구조체 내부에서 선언한 EmojiMemoryGame 인스턴스
와 EmojiMemoryGameView.swift
파일의 ContentView_Previews
구조체 내부에서 선언한 EmojiMemoryGame 인스턴스
는 별도의 인스턴스인 것이 뭔가 석연치 않았는데(동기화되어야 하는 게 아닌가 하는 멍청한 생각을 함) 오늘 생각해보니 그냥 로직을 테스트할 수 있기만 하면 되므로 개별 인스턴스여도 무관한 것 같다!