k-coding

SwiftUI ) 커스텀 Container View 만들기 ( 1 ) 본문

iOS/Swift UI

SwiftUI ) 커스텀 Container View 만들기 ( 1 )

chkhn_oiiu 2022. 8. 15. 20:00

SwiftUI ) 커스텀 Container View 만들기

 

SwiftUI에서는 VStack, HStack, List등등 내장 컨테이너 뷰가 많이 있지만, 때로 사용자가 커스텀해서 컨테이너를 정의할 수 있습니다.

 

이러한 상황은 주로 사용자가 스크롤할 수 있는 구성요소를 갖춘 뷰를 구성할 때 사용됩니다.

 

struct ContentView<Content: View>: View {
   
    let content: Content

    var body: some View {
        // 
    }
}

 

ContentView<Content: View>: View

 

해당 라인을 보면 Generic을 사용하여 ContentView에게 원하는 모든 종류의 content를 제공할 수 있지만

 

모든 content가 View 프로토콜에 적합해야한다는 문장입니다.

 

물론 <> 제네릭이 닫힌 뒤에도 ContentView 자체도 View 프로토콜에 적합해야 하므로 <>: View가 되어야 합니다.

 

 

자 그래서 이렇게만 하고 끝나면 문제점이 발생하는데 정말 간단한 뷰를 구상하는데는 아무 문제가 없습니다.

 

예를들어 텍스트 한줄만 있거나, 이미지 하나만 있는 뷰들?

 

ContentView {
    Text("안녕")
}

// 혹은

ContentView {
    Image(systemName: "circle.fill")
}

 

이런 뷰들 말이죠

 

근데 여기서 한발짝만 복잡해져도 문제가 생깁니다.

 

ContentView {
    Text("안녕")
    Image(systemName: "circle.fill")
}

이런식으로 View를 한개 이상 넘겨주려고 하게 될 경우 에러가 발생하게 됩니다.

 

이럴때는 텍스트와 이미지 각각의 뷰들을 하나의 그룹으로 묶어주면 해결됩니다.

 

ContentView {
    Group{
        Text("안녕")
        Image(systemName: "circle.fill")
    }
}

 

 

이렇게 모든 뷰들을 그룹으로 묶으면 하나의 뷰로 취급받아서 괜찮긴 하지만 매번 이렇게 그룹화하기엔 부담이 됩니다.

 

@ViewBuilder

 

그렇기때문에 한번에 content 클로저를 @ViewBuilder로 감싸주면됩니다.

 

자세하게 다루지않고 이야기 하자면 @ViewBuilder한개 이상의 View들을 받아 하나의 TupleView로 묶어서 반환해줍니다.

 

결과적으로는 위에서 Group해준것과 같은 느낌이라고 생각해도 될것같습니다.

 

이러한 @ViewBuilder를 추가하기 위해서는 init에다가 선언해주면 됩니다.

 

struct ContentView<Content: View>: View {
   
    let content: Content
    
    init (@ViewBuilder content: () -> Content) {
        self.content = content()
    }

    var body: some View {
        // 
    }
}

 

이제 이 틀을 토대로 사용자가 만들고싶은 뷰를 Custom할 수 있습니다.

 

 


참조

https://www.swiftbysundell.com/tips/creating-custom-swiftui-container-views/

 

Creating custom SwiftUI container views | Swift by Sundell

Although SwiftUI ships with a quite large number of built-in container views, such as VStack, HStack and List, sometimes we might also want to define our own custom containers as well. For example, let’s say that we’re working on an app that features a

www.swiftbysundell.com

https://www.hackingwithswift.com/books/ios-swiftui/custom-containers

 

'iOS > Swift UI' 카테고리의 다른 글

SwiftUI ) Binding<#>  (0) 2022.08.02
SwiftUI) ZStack / zIndex  (0) 2022.07.25
SwiftUI ) Identifiable 프로토콜  (0) 2022.07.24
SwiftUI ) AsyncImage  (0) 2022.07.06
SwiftUI ) 메뉴창 만들어보기  (0) 2022.07.03
Comments