ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Create custom visual effects (feat. WWDC 2024)
    SwiftUI 2024. 7. 22. 18:30

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

    이번 포스팅에서는 SwiftUI에서 커스텀한 시각 효과를 만드는 방법에 대해 학습해보겠습니다 🙋🏻

     

    WWDC 2024에서 SwiftUI로 custom visual effect를 만드는 방법에 대해 더 진보적이게 발전시켜 소개하고 있기에 한번 알아보려고 가져와봤어요 😃

     

    이전 포스팅인 What's new in SwiftUI (feat. WWDC 2024)에서 마지막쯤에 해당 비주얼 이펙트에 대해 간단히 소개하고 넘어갔는데, 이번에 더 자세히 알아보게 되었습니다ㅎㅎ

     

    What's new in SwiftUI (feat. WWDC 2024)

    안녕하세요. 그린입니다 🍏이번 포스팅부터는 조금씩 미뤄왔던 WWDC 2024 세션들을 다시 살펴보면서 관심있는 주제들에 대해 리캡을 해볼까 합니다 😃그 중에서 첫번째로 리캡해볼것은 SwiftUI입

    green1229.tistory.com

     

    그럼 시작해볼까요?

     


    Create custom visual effects

    시각적 효과 자체는 앱이 사용되고 인식되는 방식에서 아주 큰 역할을 지닙니다.

    기능이 예상대로 잘 진행되고 있다는것을 알려주기도 하고 현재 일어나고 있는 동작에 대해서 포커싱을 할 수 있도록도 해주죠.

     

     


    Scroll effects

    앱들은 대부분 스크롤뷰가 많이 사용됩니다.

     

     

    이렇게 가로로 페이징되는 스크롤뷰가 있습니다.

     

    여기서, AnimalPhoto에 Rotation Effect를 추가해볼까해요.

    SwiftUI의 scrollTransition 뷰 모디파이어를 사용해볼까요?

    아래 코드처럼 컨텐츠와 단계 인자를 사용할 수 있습니다.

     

     

    이렇게 컨텐츠에 rotationEffect와 offset을 적용할 수 있죠.

     

     

    그럼 이렇게 좌 우측 사진에 대해서 회전된 효과를 가져가며 결과적으로 스크롤이 회전 목마라 불리는 캐러셀 형태처럼 나타나게 됩니다.

    여기서 isIdentity 속성은 해당 뷰가 화면 전체에 표시되면 true가 되는 결과를 가집니다.

     

     

    또한, 다른 효과로 시차 효과를 만들 수 있습니다.

    스크롤이 넘어갈때 사진 컨텐츠는 그대로 있고 프레임이 넘어가는것처럼 변화시킬 수 있죠.

     

     

    이렇게 완전히 다른 스크롤 이펙트를 가져갈 수 있죠.

     

    즉, scrollTransition을 사용해 컨텐츠를 다양한 방법으로 조작할 수 있어요.

    스크롤 값을 기반으로 업데이트 하려는 컨텐츠에 배치할 수 있는것이죠!

     

    또한, 스크롤 프록시를 이용해볼 수 도 있어요.

     

     

    visualEffect를 이용해봅니다.

    프록시를 이용해 뷰의 위치에 따라 뷰의 색조를 변경하여 그라데이션 효과를 줄 수 있죠.

     

     

    당연히 색상 대신에도 다른 요소들을 변경할 수 있습니다.

    오프셋이나 크기, 페이드 및 흐림 효과 등 다양하게 변경해줄 수 있어요.

    모든건 스크롤뷰의 프록시를 이용할 수 있습니다.

     

    scrollTransition과 visualEffect 뷰 모디파이어를 이용하면 다양한 커스텀한 스크롤뷰 효과를 만들 수 있는것이 핵심이에요 ☺️

     

     


    Color treatments

    앱에 컬러 효과를 적용하는 방법을 보겠습니다.

    컬러는 인터페이스에 아주 중요한 역할을 하죠.

    앱의 정체성 그 자체를 부여해줄 수 있으니까요.

     

    SwiftUI에선 앱에 색상을 추가하기 위한 많은 도구들이 존재해요.

    그라데이션, 브렌드 등등 말이죠.

     

     

    그중에서도 이번 WWDC 2024에서 처음 소개되는 새로운 SwiftUI의 기능은 Mesh Gradients 입니다.

     

    메쉬 그라데이션은 동적 배경을 원하거나 표면에 시각적인 구별을 추가할 때 아주 유용해요.

     

     

    메쉬 그라데이션은 점들이 모인 그리드로 만들어 집니다.

    각 점에는 연관된 색상이 있어요.

    그리고 그 색상 사이를 보간하여 색상을 채워 생성하는 방식입니다.

     

     

    이 점들은 물론 위치등을 이동시켜 다양한 효과의 메쉬 그라데이션을 만들 수 있죠!

     

     

    색상이 부드럽게 혼합되고 서로 가까운 지점일수록 색상 전환이 더 선명해집니다.

     

    메쉬 그라데이션을 만드는 방법은 간단합니다.

     

     

    그리드를 만들기 위한 행열 갯수를 지정해줘요.

    그리고 각 포인트 지점의 위치를 정해줍니다.

    마지막으로 각 포인트에 해당하는 색상을 추가해줍니다.

     

    그럼 우리가 위 예시로 봤던 메쉬 그라데이션이 만들어지는거죠!

     

    사용 자체는 간단한데, 이걸 기획과 디자인에 따라 맞추려면 여간 수치 조정이 힘들겠다는 생각이 드네요 🥲

     


    View transitions

    이제 커스텀한 뷰 전환에 대해 알아봅니다.

    트랜지션 자체는 새 뷰를 표시하거나 필요치 않은 뷰를 제거하는 경우에 유용하죠.

     

    예를들어, Bool 변수로 뷰를 나타나고 숨겨지는 코드가 있다고 가정합니다.

     

     

    transition 뷰 모디파이어를 이용해 스케일과 투명도를 조정해봅니다.

     

     

    이런식으로 보다 자연스럽게 뷰 전환이 일어날거에요.

     

    이것보다 더 커스텀하게 구현해볼까요?

     

     

    Transition 프로토콜을 채택해 새 전환 효과를 구현해낼 수 있습니다.

     

    컨텐츠 인자는 전환하려는 컨텐츠에 대한 위치 표시자로 스크롤뷰에 대해 공유한것과 동일하게 작동해요.

    걍.. 컨텐츠라는 소리입니다.

     

    phase 인자는 뷰가 현재 표시되고 있는지 확인하고 이를 사용할 수 있는것이죠.

     

    이걸 기존 코드에 적용해볼 수 있어요.

     

     

    이렇게 커스텀한 트랜지션 구조체를 만들고 사용할 수 있습니다.

     

    잘 활용하면 아주 다양한 효과를 줄 수 있어요!

    WWDC 2023에서도 소개되었던것이기에, 중복되어 학습하는 느낌이 있긴합니다.

     

    좋은 뷰 전환 효과는 자연스럽게 들어맞아야하며, 억지로 붙인듯한 느낌이 들지 않아야합니다.

     


    Text transitions

    조금 더 나아가 텍스트 자체를 애니메이션화 시켜보려 합니다.

     

    TextRenderer가 iOS 18에 새롭게 나와 이걸 사용해볼 수 있어요.

    TextRenderer는 전체 뷰 트리에 대해 SwiftUI 텍스트가 그려지는 방식을 커스텀할 수 있는 프로토콜입니다.

     

    TextRenderer 프로토콜의 핵심은 draw 메서드입니다.

     

     

    layout 인자는 텍스트의 개별 구성 요소, 산, 실행 및 문자 모양에 접근할 수 있습니다.

    context 인자는 캔버스 뷰에서 사용되는것과 동일한 타입입니다.

     

    여기에 대해 SwiftUI 앱으로 그리는 방법을 더 알고 싶다면 아래 세션을 참고해보면 좋을것 같아요 🤔

     

     

    Add rich graphics to your SwiftUI app - WWDC21 - Videos - Apple Developer

    Learn how you can bring your graphics to life with SwiftUI. We'll begin by working with safe areas, including the keyboard safe area, and...

    developer.apple.com

     

    draw 메서드를 보면, for문을 사용해 레이아웃의 개별 줄을 반복하고 컨텍스트에 그리기만 하면 됩니다.

    그러면 기본 렌더링 동작이 제공되죠.

     

     

    이제 전환을 진행하기위해서, 속성들을 추가해야 합니다.

    elapsedTime는 지금까지 경과된 시간을 나타냅니다.

    elementDuration은 개별 줄이나 문자에 애니메이션을 적용하는데 소요된 시간입니다.

    totalDuration은 전체 전환에 소요된 시간입니다.

     

    SwiftUI가 자동으로 elapsedTime 값에 애니메이션을 적용하도록 하기 위해 Animatable 프로토콜을 구현해야 합니다.

     

    이제 draw 메서드를 더 추가 구현하여 애니메이션을 구현할 수 있어요.

     

     

    개별 라인 하나씩 애니메이션을 적용하는것이죠.

    적용된 복사본을 만들어 draw를 호출하는것이죠.

     

     

    해당 draw 메서드는 이렇게 커스텀하게 구현을 정의할 수 있습니다.

     

    더 추가적으로 spring 효과를 줄수도 있죠.

     

     

    마지막 옵션으로 픽셀 양자화를 해제하면 스프링 효과가 안정될 때 지터를 피할 수 있어요.

    (지터는 간단히 디지털 전송에서의 시간 차로 인한 오류라고 합니다.)

     

    이제 트랜지션 프로토콜을 채택해 만들어진걸 활용할 수 있습니다.

     

     

    renderer에 해당 텍스트 렌더러를 활용하면 됩니다.

     

     

    요렇게 텍스트가 나타나게 커스텀한 애니메이션을 적용할 수 있는것이죠.

     

    만약 한글자마다 적용하고 싶다면 아래 코드를 유심히 보면 좋습니다.

     

     

    flattenedRunSlices를 이용하여 쪼개주면 되죠.

     

    그럼 이제 구동시키면 실제로 한글자씩 나타날거에요.

     

    iOS 18에선 TextRenderer뿐 아니라, TextAttribute 프로토콜도 도입되었습니다.

     

     

    해당 프로토콜을 구현하면 내 텍스트의 데이터를 TextRenderer로 전달해줄 수 있습니다.

    텍스트 범위를 표시하는데만 사용되기 때문에 실제로 TextAttribute 구조체에 멤버 변수를 추가할 필요는 없습니다.

     

     

    draw에서 해당 Attribute-Type을 키로 사용하여 실행 시 EmphasisAttribute가 있는지 확인합니다.

    존재하면 이전과 동일하게 방식으로 슬라이스를 반복하고, 없다면 0.2초에 걸쳐 실행 중에 빠르게 페이드되도록합니다.

     

    그럼 이렇게 나타납니다.

     

     


    Metal shaders

    shaders는 장치의 GPU에서 직접 다양한 렌더링 효과를 개선하는 작은 프로그램입니다.

    앞서 살펴본 Mesh Gradients와 같은것들도 SwiftUI가 내부적으로 shaders를 사용한것이죠.

    iOS 17에서 도입된 SwiftUI shaders를 사용하면 동일한 수준의 성능을 발휘하고 각자의 원하는 이펙트를 구현해낼 수 있죠.

     

     

    ShaderLibrary에서 해당 이름의 함수를 호출해 SwiftUI에서 Shader를 인스턴스화 시킵니다.

    여기에 색상, 숫자, 이미지와 같은 추가 매개변수를 shaders 함수에 전달할 수도 있습니다.

    layerEffect 뷰 모디파이어를 사용해 효과를 뷰에 적용하면 이제 SwiftUI는 뷰의 모든 단일 픽셀에 대해 shaders 함수를 호출합니다.

     

    이를 실시간으로 가능하게 하기 위해 shaders는 이와 같은 고도의 병렬 작업에 최적화된 장치의 GPU에서 실행됩니다.

     

    그러나, GPU 프로그래밍의 특수한 특성으로 Shader 자체는 Swift로 작성할 수 없어요 🥲

    대신, Metal Shading Language, 줄여서 Metal로 작성됩니다.

     

     

    앞서 예시에 나온 shaders의 Metal 파일입니다.

    SwiftUI가 GPU에서 각 뷰 픽셀에 대해 실행하는 함수이며, 실행될 때 포지션 인자는 해당 픽셀의 위치를 참조합니다.

    또한, Color와 같은 타입을 Metal에서 사용할 수 있는 표현으로 변환해주죠.

    Metal은 이와 같이 벡터 유형을 많이 사용합니다.

    예시로, half4는 16비트 부동 소수점 숫자의 4개 구성 요소 벡터에요.

    float2는 32비트 부동 소수점 숫자의 2성분 벡터이며 2D 점 혹은 디멘션에 자주 사용되죠!

     

    SwiftUI에서 shaders는 커스텀한 채우기 / 색상 효과 / 왜곡 효과 / 레이어 효과에서 사용할 수 있습니다.

     

    여기서, 이번 세션에선 레이어 효과가 가장 강력하고 효과적으로 다른 두 효과들의 상위이기에 레이어 이펙트로 보겠습니다.

     

     

    Shaders를 이용해 이런 효과를 만들 수 있어요.

     

     

    Metal을 이렇게 구현해주면 된다고 합니다.

    (어렵네요 😭 그냥 이렇게 사용하는구나 흐름을 이해해보겠습니다.)

     

    그 다음 뷰 모디파이어를 만들어서 적용해봐야겠죠?

     

     

    이렇게 body까지 구성해 뷰 모디파이어를 만듭니다.

     

    그 다음으로 해당 이펙트 구조체를 만들어요.

     

    이제 트리거 값이 업데이트될 때마다 애니메이션이 됩니다.

    그럼 이제 해당 이펙트를 필요한곳에 사용하면 끝이죠 😄

     


    마무리

    이렇게 이번 WWDC 2024에서 새로 나온 SwiftUI의 비주얼 이펙트들에 대해 알아봤습니다.

    생각보다 딥한것도 있지만, 잘 활용해볼 수 있겠는데요?!

     


    레퍼런스

     

    Create custom visual effects with SwiftUI - WWDC24 - Videos - Apple Developer

    Discover how to create stunning visual effects in SwiftUI. Learn to build unique scroll effects, rich color treatments, and custom...

    developer.apple.com

    'SwiftUI' 카테고리의 다른 글

    SwiftUI - AnyLayout  (4) 2024.08.29
    Enhance your UI animations and transitions (feat. WWDC 2024)  (80) 2024.07.29
    SwiftUI - ViewThatFits  (73) 2024.07.15
    Demystify SwiftUI containers (feat. WWDC 2024)  (76) 2024.07.11
    What's new in SwiftUI (feat. WWDC 2024)  (78) 2024.07.08
Designed by Tistory.