SwiftUI๋ก ๋ทฐ๋ฅผ ๋ง๋ค๋ค๋ณด๋ฉด ViewBuilder๋ผ๋ ํ๋กํผํฐ ๋ํผ๋ฅผ ๋ง๋๊ฒ ๋๋ค. ์ด ์น๊ตฌ์ ์ญํ ์ ๋ญ๊ณ ์ด๋ป๊ฒ ๋ค์ํ ๋ทฐ๋ค์ ํ๋๋ก ๋ฌถ์ด์ฃผ๋ ๊ฑธ๊น๋ผ๋ ์๋ฌธ์ด ์๊ฒผ๋ค. ๊ทธ๋์ ํด๋น ๋ด์ฉ์ ๋ํด ์ข ๋ ๊ณต๋ถํด๋ณด๊ฒ ๋์๋ค.
ViewBuilder์ ๋ํด ์ฐพ์๋ณด๋ค๋ณด๋ resultBuilder์ ๋ํ ๋ด์ฉ์ ์ฐพ์๋ณผ ์ ์์๋ค. @resuiltBuilder
๋ ๋ฌด์์ผ๊น? ๋จผ์ ์์ ์ฝ๋๋ฅผ ๋ณด์
@resultBuilder
struct AddEvenNumbers {
static func buildBlock(_ components: Int...) -> Int {
var final: Int = 0
for part in components {
final += part % 2 == 0 ? part : 0
}
return final
}
}
@AddEvenNumbers
var result: Int {
1
2
3
4
5
6
7
8
9
10
}
print(result)//30
๋ค์ ์ฝ๋๋ ์ง์๋ง ๊ณจ๋ผ์ ๊ทธ ํฉ์ ๋ํด์ฃผ๋ @resuiltBuilder
์ด๋ค. ๋จผ์ @resuiltBuilder
๋ฅผ ์ ์ฉํ ๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑํด์ ํ๋กํผํฐ ๋ํผ๋ฅผ ๋ง๋ค์ด์ฃผ๊ณ ๋ด๋ถ์์ ์์ธ ๋ก์ง์ ๊ตฌํํ๋ค. ๊ทธ๋ฌ๋ฉด ์์ฑํ ํ๋กํผํฐ ๋ํผ๋ฅผ ์ ์ฉํ๋ฉด result ๋ณ์์ฒ๋ผ ํ์ฉํ ์ ์๋ค. ์์๋ค์ ๋์ดํ๊ณ ํด๋น ์์๋ค์ ์ ํด์ง ๊ท์น์ ๋ฐ๋ผ ๊ฒฐํฉ, ์ฒ๋ฆฌํด์ฃผ๋ ๊ฒ์ด ๋ฐ๋ก @resuiltBuilder
์ด๋ค. @resuiltBuilder
๋ฅผ ๊ตฌํํด๋ณด๋ฉด buildBlock
์ ๊ฐ์ ํ์ ๋ฉ์๋๋ถํฐ ์์ํด์ if๋ฌธ, Optional์ผ ๊ฒฝ์ฐ ๊ฐ๋ค์ ์ฒ๋ฆฌํ๋ ๋ฉ์๋๋ค์ด ๊ตฌํ๋์ด ์๋ค. ํด๋น ๋ฉ์๋๋ค์ ํ์ฉํด์ ์์๋ค์ ๋ค์ํ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ค.
result ๋ณ์์ ํํ๋ฅผ ๋ณด๋ฉด ๋น์ทํ ์ด๋ค๊ฒ ๋ ์ค๋ฅด์ง ์๋โฆ? ๋ง๋ค ๋ฐ๋ก SwiftUI์ View ์ ์ธ ๋ฐฉ์์ด๋ค. ๋ ๋ฐฉ์์ด ๋น์ทํด ๋ณด์ด๋ ์ด์ ๋ SwiftUI์ ViewBuilder
๋ @resuiltBuilder
๋ฅผ ์ฑํํด์ ๋ง๋ค์ด์ง ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
ViewBuilder๋ ์ผ๋ฐ์ ์ผ๋ก ์์ ๋ทฐ๋ฅผ ์์ฑํ๋ ํด๋ก์ ๋งค๊ฐ๋ณ์์ ๋ํ ๋งค๊ฐ๋ณ์ ์์ฑ์ผ๋ก ์ฌ์ฉ๋๋ฉฐ, ์ด๋ฌํ ํด๋ก์ ๊ฐ ์ฌ๋ฌ ๊ฐ์ ์์ ๋ทฐ๋ฅผ ์ ๊ณตํ ์ ์๋๋ก ํฉ๋๋ค.
ViewBuilder๋ ํ๋์ ํด๋ก์ ๋ก ์ฌ๋ฌ ๊ฐ์ ์์ ๋ทฐ๋ฅผ ๋ค๋ฃฐ ์ ์๋๋ก ํ๋ค. ์ฐ๋ฆฌ๊ฐ VStack๊ณผ ๊ฐ์ ์คํ ๋ด๋ถ์ ์ฌ๋ฌ ์์ ๋ทฐ๋ค์ ์ถ๊ฐํ๊ณ ์ฝ๊ฒ ๋ค๋ฃฐ ์ ์๋ ๊ฒ๋ VStack ๋ด๋ถ๋ฅผ ๋ณด๋ฉด ํด๋ก์ ๋งค๊ฐ๋ณ์์ ViewBuilder ์์ฑ์ด ์ ์ฉ๋์ด ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๋ ๋ฏ ์ฐ๋ฆฌ๋ ViewBuilder๋ฅผ ํ์ฉํด์ ์ฌ๋ฌ ์์ ๋ทฐ๋ค์ ํ ๋ฒ์ ์ ์ํ๊ณ ๊ด๋ฆฌํ ์ ์๋ค. ๋ํ ViewBuilder ํ์์ผ๋ก ๋ทฐ๋ฅผ ๊ด๋ฆฌํ๋ฉด ๊ฐ๋ ์ฑ๋ ์ข๋ค!
ViewBuilder๋ ๋ค์๊ณผ ๊ฐ์ ์ํฉ์์ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋ ์ ์๋ค.
private func ImageCellView(model: ImageDTO) -> some View {
if let image = imageDict[model.id] {
thumbnailImageView(image: image)
.onAppear{
debugPrint("original appeared \\(model.id)")
}
} else {
waitingFetchingView(model: model)
}
}
๋ค์ ์ฝ๋๋ ๋์
๋๋ฆฌ์ ์ด๋ฏธ์ง๊ฐ ์๋ค๋ฉด PlaceHolder(waitingFetchingView
)๋ฅผ ๋ณด์ฌ์ฃผ๊ณ , ์๋ค๋ฉด thumbnailImageVIew
๋ฅผ ๋ณด์ฌ์ฃผ๋ ๋ฉ์๋์ด๋ค. ๊ฐ๋ง ๋ณด๋ฉด ๋ก์ง์ ๋ฌธ์ ๊ฐ ์์ด๋ณด์ด์ง๋ง ํด๋น ๋ฉ์๋๋ ์ปดํ์ผ ์ค๋ฅ๊ฐ ๋๋ค. ์๋ํ๋ฉด ๋ฆฌํด ํ์
์ด some View
์ด๊ธฐ ๋๋ฌธ์ ์ปดํ์ผ ๊ณผ์ ์์ ํ๋์ ํ์
์ผ๋ก ์ถ๋ก ์ด ๊ฐ๋ฅํด์ผ ํ๋๋ฐ ํด๋น ๋ฉ์๋๋ ๋ ๊ฐ์ง ํ์
์ ๋ทฐ๊ฐ ๋์์ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ์ปดํ์ผ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค. ๊ทธ๋ด ๋ ์ ๊ธฐ์ ViewBuilder ์์ฑ์ ๋ํด์ฃผ๋ฉด ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ค ์ ์๋ค.
@ViewBuilder
private func ImageCellView(model: ImageDTO) -> some View { ... }