Swift에서는 함수에서 함수를 리턴할 수도 있다.
또 UIKit을 사용하다보면, View, ViewController 등을 리턴할 수도 있다.
그럼 SwiftUI에서도 함수를 통해 View를 반환할 수 있을까?
(View가 리턴 타입이 될 수 있을까?)
되는지 안 되는지 모르니까 일단 해보자!
func notUseViewBuilder(isFirst: Bool) -> some View {
if isFirst {
return FirstView()
} else {
return SecondView()
}
}
무작정 코드를 작성하고 빌드를 했다.
Opaque Type이긴한데 기본 타입을 알 수 없다고 한다.
검색해보니 이럴 때 ViewBuiler를 사용하면 된다고 한다.
@ViewBuilder
func useViewBuilder(isFirst: Bool) -> some View {
if isFirst {
return FirstView()
} else {
return SecondView()
}
}
여전히 오류가 있고, 경고 하나가 추가된다.
위 Fix를 누르면 @ViewBuilder가
아래 Fix를 누르면 return 키워드가 사라진다.
@ViewBuilder는 방금 붙인거니 지운다면 의미가 없다.
아래 Fix를 눌러보자
@ViewBuilder
func useViewBuilder(isFirst: Bool) -> some View {
if isFirst {
FirstView()
} else {
SecondView()
}
}
빌드가 된다!
경고 문구를 다시보면 ViewBuilder에서는 return키워드를 안 쓰다는 내용이다.
문법의 일종이라고 본다.
이제 함수로 여러 타입의 View를 반환할 수 있게 되었다!
사실 방법이 하나만 있는 것은 아니다.
AnyView
func useAnyView(isFirst: Bool) -> some View {
if isFirst {
return AnyView(FirstView())
} else {
return AnyView(SecondView())
}
}
AnyView로 각 View를 감싸면 가능하다.
Viewbuilder를 안 썼으니 return를 써줘야한다.
Group or Stack
func group() -> some View {
Group {
if self.isAnyView {
FirstView()
} else {
SecondView()
}
}
}
func stack() -> some View {
VStack { // or HStack, ZStack
if self.isAnyView {
FirstView()
} else {
SecondView()
}
}
}
Group이나 Stack으로 감싸게 되면 반환이 가능하다.
ViewBuilder를 또 어디서 사용할 수 있을까?
프로퍼티
@ViewBuilder var twoText: some View {
Text("Text")
Text("Properties")
}
클로저 (함수 타입 인자)
func viewBuilderParameter<V: View>(@ViewBuilder view: (String) -> V) {
// Code
}
View를 Struct로 정의해서 사용할 수도 있지만, 프로퍼티로 사용하거나 함수에서 사용한다면 위의 코드처럼 사용이 가능하다.
VStack이나 HStack 등에서 View의 개수가 10개를 넘어가면 오류가 나타난다.
11번째 argument부터 문제가 생기는데
알고보니 공식문서에 그 답이 있었다.
Apple Developer Documentation
developer.apple.com
최대 10개의 Content를 받도록 구현되어있고, 해당 Content들은 TupleView로 반환된다.
하나 이상의 View가 Closure에서 사용된다면 @ViewBuilder 키워드를 사용하게 된다.
@ViewBuilder 키워드도 ViewModifier 프로토콜처럼 적절히 활용해보면 좋을거같다!
'iOS > SwiftUI' 카테고리의 다른 글
[SwiftUI] ViewModifier (0) | 2022.07.01 |
---|---|
[SwiftUI] Shapes (0) | 2022.04.24 |
[SwiftUI] User Interface Elements (0) | 2022.04.24 |
[SwiftUI] View Containers (0) | 2022.04.24 |
[SwiftUI] @GestureState, @Namespace, @ScaledMetric (0) | 2022.04.19 |