ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SwiftUI - View
    SwiftUI 2022. 12. 24. 12:16

    안녕하세요. 그린입니다🍏

    이번 포스팅에서는 SwiftUI의 View Protocol에 대해 알아보겠습니다🙌

     

    SwiftUI로 뷰를 만들면서 꼭 만나는 개념이 있습니다.

    바로 View를 채택하는것인데요.

    그러니까 이 View는 프로토콜입니다.

    이 프로토콜을 별 고민없이 채택하고 뷰를 그려줬었는데 오늘은 이 프로토콜이 어떻게 구성되어 있는지에 대해서 알아보겠습니다.

     

    그럼 바로 보시죠🕺🏻

     

    View

    공식문서에서는 View 프로토콜을 앱 사용자 인터페이스의 일부를 보여주고 뷰를 구성하는데 사용하는 모디파이어 즉 수정자를 제공하는 프로토콜이라고 합니다.

    쉽게 정리하면, 뷰를 그리기 위해서 채택하는 프로토콜이라고 이해하고 어떻게 구성되어 있는지 보시죠~!

    public protocol View {
      associatedtype Body : View
      @ViewBuilder @MainActor var body: Self.Body { get }
    }

    공식문서에는 나와 있지 않지만 소스 코드를 들어가보면 View 프로토콜의 정의를 볼 수 있습니다.

    연관 타입으로 View 즉, 자신을 Body라고 칭하고 @ViewBuilder와 @MainActor 프로퍼티 래퍼를 지닌 body 프로퍼티를 가집니다.

    이 타입은 자신의 View 타입이죠.

    결국 이 프로토콜을 채택하면 body 프로퍼티를 구현해야되고 우리는 습관처럼 아래와 같이 구현하고 있었죠.

    struct MyView: View {
      var body: some View {
          Text("Hello, World!")
      }
    }

    MyView 구조체 즉 해당 뷰는 View 프로토콜을 채택하고 프로토콜에서 필요한 body 프로퍼티에 원하는 형태의 뷰 컴포넌트를 나열해 뷰를 만들어주게 되는것이죠.

     

    여기서 View 프로토콜에서 @ViewBuilder와 @MainActor 개념이 나왔는데 이 부분을 조금 더 들여다 보겠습니다👀

     

    @ViewBuilder

    공식문서에서는 뷰빌더를 구조체로 클로저에서 뷰를 구성하는 커스텀 매개변수 속성이라고 소개합니다.

    @resultBuilder struct ViewBuilder

    정의는 위와 같아요.

    여기서 또, @resultBuilder를 사용하는데 이건 또 밑에서 간단히 알아보도록해요.

    우선 요약만 해보자면 뷰를 구성하기 위해 들어갈 뷰 컴포넌트들의 배열을 컴마(,) 없이 나열하여 사용할 수 있도록 도와줍니다.

     

    마찬가지로 @ViewBuilder에 대해 소스코드에서 확인해보면 아래와 같이 정의되어 있습니다.

    @resultBuilder public struct ViewBuilder {
      public static func buildBlock() -> EmptyView
      public static func buildBlock<Content>(_ content: Content) -> Content where Content : View
    }

    제네릭으로 들어가는 Content는 View 타입으로 해당 뷰를 받아 결국 최종 뷰를 그려주도록 buildBlock 메서드를 이용합니다.

     

    결국 우리는 @ViewBuilder를 이용해 View를 구성 시 아래와 같이 컴마 없이 뷰 컴포넌트를 나열해 하나의 원하는 뷰를 만들 수 있어요.

    struct MyView: View {
      var body: some View {
        Text("Hello, World!")
          
        Text("Green")
          
        Button(
          action: { },
          label: { Text("Button") }
        )
          
        Image(systemName: "close")
      }
    }

     

    공식문서에서 buildBlock을 보면 다양하게 존재합니다.

    즉, 파라미터로 넘겨주는 뷰의 갯수에 따라서 다양하게 존재하죠.

    즉 뷰 컴포넌트의 배열을 가지고 하나의 뷰로 합쳐 만들어주는 역할을 하는것이죠.

    추측하기론, 간혹 한 뷰에 너무 많은 뷰 컴포넌트를 혼합하면 아래와 같이 너무 많은 인자를 호출했다는 에러가 납니다.

    이 경우가 여기에 정의된 뷰의 갯수를 넘어서지 않을까 생각이 드네요🤔

     

    그럼 아주 간단히 아까 짚으려했던 @resultBuilder에 대해 알아 보시죠!

     

    @resultBuilder

    여기서는 아주 간단히만 알아보고 다른 포스팅으로 조금 구체적으로 알아볼께요!

    Swift 5.4에서부터 도입된 개념으로 컴마(,) 없이 배열을 구성하는 기능에 사용합니다.

    즉, 해당 프로퍼티 래퍼로 선언하면 필요한 buildBlock 메서드를 정의해야합니다.

    @resultBuilder
    struct SimpleStringBuilder {
      static func buildBlock(_ parts: String...) -> String {
          parts.joined(separator: "\n")
      }
    }

    위와 같이 샘플로 보여드린것처럼 받아온 타입들을 합쳐주는것이죠.

    해당 메서드가 있기에 컴마(,) 없이도 선언이 가능한것입니다.

    결과적으로 다시 SwiftUI로 돌아와서 resultBuilder로 선언된 ViewBuilder를 사용함으로 뷰 컴포넌트들을 컴마(,) 없이 나열하여도 괜찮다는것이죠🙌

     

    그럼 이어서 @MainActor에 대해 알아보겠습니다!

     

    @MainActor

    동시성의 API중 하나로 공식문서에서는 메인 스레드에서 동작을 시켜주도록 해줍니다.

    즉 DispatchQueue.main으로 감싸줘서 다루지 않아도 늘 뷰는 메인 스레드에서 동작할 수 있게 해주는것이죠.

    뷰의 업데이트는 메인 스레드에서 이뤄져야한다는것은 이미 아실거라 이걸 내포해주는 기능입니다.

    @globalActor final actor MainActor

    선언은 위와 같습니다.

     

    자 그럼 View 프로토콜에 대해 어느정도 구성과 왜 채택하여 사용해야 되는지에 대해 알아봤습니다!

    다음 포스팅에서는 조금 더 심층적으로 들어가 왜 SwiftUI에서는 View를 class가 아닌 struct로 만드는지에 대해 알아볼께요!

     

    마무리

    어느정도 View 프로토콜에 대해 이해가 되었네요!

    이번 포스팅에서 조금 미비한 부분들은 다음 포스팅에서 조금 더 심화적으로 다뤄보겠습니다🙌

     

    [참고 자료]

    https://developer.apple.com/documentation/swiftui/view

     

    Apple Developer Documentation

     

    developer.apple.com

    https://ios-development.tistory.com/1065

     

    [iOS - swiftUI] View Protocol (뷰 프로토콜)

    목차) SwiftUI의 기본 - 목차 링크 View Protocol View 프로토콜 프로토콜이고, body라는 computed property를 가지고 있는 타입 view를 입력할 수 있게하는 인터페이스를 제공하는 역할 @available(iOS 13.0, macOS 10.15

    ios-development.tistory.com

    https://developer.apple.com/documentation/swiftui/viewbuilder

     

    Apple Developer Documentation

     

    developer.apple.com

    https://www.hackingwithswift.com/swift/5.4/result-builders

     

    Result builders – available from Swift 5.4

    Link copied to your pasteboard.

    www.hackingwithswift.com

    https://developer.apple.com/documentation/swift/mainactor

     

    Apple Developer Documentation

     

    developer.apple.com

Designed by Tistory.