안녕하세요.
ViewBuilder는 언제 사용할까요?
# 예시
# some View를 반환하는 함수에서 에러 나요ㅠㅠ
간단한 예시로 Text 뷰를 반환하는 함수가 있다고 해볼게요.
여기까진 문제없어요ㅎㅎ
살짝 복잡하게 가볼게요.
Toggle 버튼 on/off로 Text 뷰와 Button 뷰가 번갈아 보이도록 만들어볼게요.
문제없어 보였지만 view 함수에서 이런 에러가 발생합니다.
error: Function declares an opaque return type 'some View', but the return statements in its body do not have matching underlying types
some View는 opaque type이고 underlying type이 1가지만 될 수 있습니다. 하지만 view 함수 내에선 underlying type이 2가지이기 때문에 에러가 발생한 것입니다.
(어쩔 땐 Text 뷰를 반환하고 어쩔 땐 Button 뷰를 반환하니까요.)
## 권장하진 않지만 AnyView를 사용하면 해결 가능.
이때 AnyView를 활용하면 해결할 수는 있어요.
하지만 AnyView는 'type-erasing wrapper type'이라 불리며 AnyView로 감싸면 SwiftUI가 내부 구조를 알 수 없게 되기 때문에 사용을 권장하지 않습니다.
(이 부분은 나중에 WWDC 영상 공부하면서 더 정리할게요!)
무엇보다 함수 내의 모든 View를 AnyView로 감싸줘야 하니 코드 가독성도 떨어지게 됩니다.
## @ViewBuilder를 사용하세요.
이럴 때 @ViewBuilder를 사용하면 좋다고 해요.
[주의] @ViewBuilder 안에선 return 구문을 명시적으로 호출하지 않습니다.
@ViewBuilder 안에서 return 구문을 사용하면 return 구문을 명시적으로 사용하지 말라는 경고 문구가 뜹니다.
> Application of result builder 'ViewBuilder' disabled by explicit 'return' statement
그 이유는 @ViewBuilder는 @resultBuilder이기 때문이에요.
@resultBuilder가 뭔지는 여기에 정리했으니 참고하세요.
@ViewBuilder를 사용하니 가독성도 좋아지고 AnyView를 사용하지 않은 덕분에 SwiftUI 내부적으로 Conditional Content의 tree를 구성할 수 있게 됩니다.ㅎㅎ
# 정리
자. 다시 글의 처음으로 돌아와서... ViewBuilder는 언제 사용하면 좋을까요?
ViewBuilder는 여러 상태값에 따라서 여러 뷰를 반환하고 싶을 때 ViewBuilder를 사용하면 좋습니다.
사실 이 내용은 @ViewBuilder 가이드 하단에 적혀 있었는데요.
가이드에서 말하는 multiple-statement와 serveral child views의 의미가 제가 말한 '여러 상태값에 따라서 여러 뷰'를 의미하는 것 같아요ㅎㅎ
# 참고
https://developer.apple.com/documentation/swiftui/viewbuilder
https://levelup.gitconnected.com/viewbuilder-in-swiftui-4a5bca1fbb85
https://ghazi-tozri.medium.com/swiftui-viewbuilder-31faef1a5469
https://stackoverflow.com/questions/63815577/swiftui-struct-view-vs-viewbuilder
https://developer.apple.com/videos/play/wwdc2021/10022
이번 글은 여기서 마무리.
'SwiftUI' 카테고리의 다른 글
Preview Content 란..? (1) | 2024.11.01 |
---|---|
TCA(10) : Custom Dependency (1) | 2023.10.10 |
TCA(9) : Dependency (0) | 2023.10.01 |
WebView 당겨서 새로고침(Pull to Refresh) 기능 추가하기 (0) | 2023.09.05 |
TCA(8) : Binding (1) | 2023.08.09 |