SwiftUI

@ViewBuilder는 언제 사용할까?

Phililip
728x90

안녕하세요.

 

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' 카테고리의 다른 글

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
TCA(7) : 0.54.0 -> 1.0.0 업데이트  (0) 2023.08.07