[회고] 신입 iOS 개발자가 되기까지 feat. 카카오 자세히보기

🍎 Apple/SwiftUI

[SwiftUI] Opaque Type, ViewModifier, View Combiner

inu 2022. 3. 30. 11:31
반응형

Opaque Type

  • some View는 View의 한 종류인것만 결정되어있고, 자세히 어떤 View인지는 컴파일러가 직접 판단하는 View입니다.
  • Some은 Opaque Type (불투명 타입)을 표현합니다.
    • Opaque Type Some은 computed property 혹은 함수의 구체적인 return type을 숨길 수 있도록 해줍니다. 이를 통해 간결한 코드 작성이 가능해집니다.
    • Opaque Type은 Reverse Generic Type이라고 불리기도 합니다.
    • Generic은 함수가 타입 제약을 유지하면서 다양한 타입을 허용할 수 있도록 합니다.
    • Opaque은 함수가 자유로운 타입을 리턴할 수 있도록 합니다.

ViewModifier

  • SwiftUI에 내장된 프로토콜로, 기존의 뷰 또는 다른 View Modifier에 적용시켜 또 다른 버전을 만들 수 있는 Modifier입니다.
  • 기존의 View 또는 Modifier를 추가적으로 꾸며 새로운 Modifier를 생성할 수 있습니다.
  • 아래는 대표적인 예시입니다. 기존에 존재하는 content에 내장 Modifier를 사용하여 'BorderedCaption'라는 하나의 Modifier를 만들었습니다.
struct BorderedCaption: ViewModifier {
    func body(content: Content) -> some View {
        content
            .font(.caption2)
            .padding(10)
            .overlay(
                RoundedRectangle(cornerRadius: 15)
                    .stroke(lineWidth: 1)
            )
            .foregroundColor(Color.blue)
    }
}
  • 이렇게 생성된 Modifier는 적용이 필요한 View 뒤에 .modifier(modifier: T)를 입력하는 것으로 사용할 수 있습니다.
struct ContentView: View {
  var body: some View {
    Text("Downtown Bus")
      .modifier(TextModifier())
  }
}
  • modifier를 extension에 적용해놓아 더 선언적으로 사용할수도 있습니다.
extension View {
    func borderedCaption() -> some View {
        modifier(BorderedCaption())
    }
}
struct ContentView: View {
  var body: some View {
    Text("Downtown Bus")
      .borderedCaption()
  }
}
  • Modifier를 적용하면 매번 새로운 View가 생성되는 것이나 마찬가지입니다.
    • SwiftUI에서 View 자체는 구조체 형태로 구성되는데, 구조체는 immutable하기 때문에 내부를 수정할 수 없습니다. 따라서 변화가 생기면 수정사항이 반영된 새로운 View를 리턴하는 것입니다.

View Combiner

  • View Combiner는 내부에 존재하는 Bag of views를 조합하여 하나의 View를 반환합니다.
  • 대표적인 예로 ZStack이 있습니다. 이는 내부에 존재하는 view들을 z축을 기준으로 조합합니다.
  • 이 외에도 HStack과 VStack도 존재합니다.
  • HStack : view들을 horizontal(가로)축을 기준으로 조합
  • VStack : view들을 vertical(세로)축을 기준으로 조합
ZStack {
    //view builder : Tuple 형태의 View를 생성해 View Combiner인 ZStack에 넘깁니다.
    RoundedRectangle(cornerRadius: 25.0)
        .stroke(lineWidth: 3)

    Text("Hello World!")
        .foregroundColor(.orange)
}

참고

반응형