@ViewBuilder
You typically use ViewBuilder as a parameter attribute for child view-producing closure parameters, allowing those closures to provide multiple child views. For example, the following contextMenu function accepts a closure that produces one or more views via the view builder.
func contextMenu<MenuItems: View>(
@ViewBuilder menuItems: () -> MenuItems
) -> some View
이를 통해 contextMenu의 클로저를 통해 하나이상의 뷰가 클로저안에 들어갈수 있다.
마찬가지로 Hstack을 보자. 마지막 파라미터로 @ViewBuilder를 통해 Hstack안에 여러 뷰들을 넣어줄 수 있다.
@inlinable public init(alignment: VerticalAlignment = .center,
spacing: CGFloat? = nil,
@ViewBuilder content: () -> Content)
즉! 어떠한 뷰밑에 여러 뷰들을 넣어주고 싶다? => @ViewBuilder특성을 붙여줘야함
우리가 제일 자주쓰는 body는 암시적으로 @ViewBuilder가 선언되어있음.
그럼 이걸 언제써?
=> 커스텀하는 뷰가 필요할때 사용하게 된다.
@resultBuilder
위의 ViewBuilder 해체쇼를 하던 중 앞에 @resultBuilder가 붙어있다. 엥? 이게 모지? 🤖등장
프로퍼티래퍼인 @resultBuilder를 구조체에다 달아주면 데이터들을 넘겨받아 buildBlock method를 통해 데이터의 나열을 해석한다.. 이게 공식문서의 번역. 여전히 위 아래 둘다 몬소린지 몰겟다.
자 위에서 viewBuilder라는 놈은 HStack, VStack, Text등 여러뷰들을 클로저안에 넣어줄수 있는 프로퍼티래퍼라고 설명을 하였다.
그런데 다른 언어에서 보면 구분을 할때 ,(콤마)를 사용한다. 그런데 우리가 그동안 사용했던 코드들을 보면 뷰들 사이에 콤마는 존재하지 않는다. 왜일까? 그에 대한 대답이 resultBuilder가 된다.
컴파일타임때 자동으로 여러개를 취합하여 return키워드 없이 하나의 결과로 반환하도록 도와준다!!
/// Builds an empty view from a block containing no statements.
public static func buildBlock() -> EmptyView
/// Passes a single view written as a child view through unmodified.
///
/// An example of a single view written as a child view is
/// `{ Text("Hello") }`.
public static func buildBlock<Content>(_ content: Content) -> Content where Content : View
public static func buildBlock<each Content>(_ content: repeat each Content) -> TupleView<(repeat each Content)> where repeat each Content : View
@resultBuilder를 적으면 반드시 buildBlock 메서드를 작성해주어야한다.
위의viewBuilder를 보면 buildBlock() -> EmptyView를통해 우리는 비어있는 뷰와 그뒤의 메서드를 통해 하나만 있는 것도 만들수 있고 마지막으로 맨 아래있는 메서드를 통해 여러뷰들을 취합하여 return없이!! 보여줄수 있다. 또한
func addAllString(_ a: String, _ b: String, _ strings: String...) -> String{
var temp = a + b
for string in strings {
temp + string
}
return temp
}
addAllString(a: "Hi", b: "Im", "SunDay", "Or", "sunho", "LEE")
뭐 결과는 아시죠? 근데 누가봐도 코드가 더럽지 않아여? 이걸 클린하게 바꿔봅시다
@resultBuilder
struct StringBuilder {
static func buildBlock(_ components: String...) -> String {
components.joined(separtor: " ")
}
}
func addAllString(@StringBuilder _ strings: () -> String) -> String {
strings()
}
let answer = addAllString {
"Hi"
"Im"
"sunday"
"sunhO"
}
이것이 resultBuilder의 힘이다.
'SWIFTUI' 카테고리의 다른 글
some(Opaque Type)&any Keyword (1) | 2024.02.29 |
---|---|
근본으로 돌아가자(4)-@State,@StateObject,@ObservedObject (2) | 2024.02.27 |
근본으로 돌아가자(3)-View Layout (2) | 2024.02.26 |
근본으로 돌아가자(2) - animation & iOS 17에서 바뀐것들 (0) | 2023.12.14 |
View Modifier (0) | 2023.12.14 |