[SwiftUI] Animation

이은수, Steve·2025년 5월 3일

SwiftUI

목록 보기
5/6
post-thumbnail

애니메이션?

애니메이션이란 뭘까요?

사실 애니메이션이라고 하면 위 이미지 처럼 만화같은것을 상상하겠지만 SwiftUI에서 애니메이션은 우리가 자주사용하는 파워포인트나 키노트의 전환 애니메이션에 가깝습니다.


애니메이션은 발표용 프로그램에서 사용하는 화면 전환 효과에 가깝습니다.

실제로 SwiftUI에서 사용하는 애니메이션 효과에도 컴포넌트의 크기변화, 위치변화, 색변화 등등 간단한 효과만 지정할 수 있습니다.

물론 우리가 아는 애니메이션같은 형태도 만들 수 있겠지만 그러면 엄청난 노력과 시간이 들어가겠죠?

그런 어려운 효과는 보통 gif로 넣거나 lottie같은 외부 라이브러리를 사용하는게 일반적입니다.

주관적 정의

제 나름대로 SwiftUI에서의 애니메이션을 한마디로 정의하자면 다음과 같이 말할 수 있을거 같습니다.

상태 변화에 대해 UI를 업데이트(렌더링) 할때 그 변화를 부드럽게 시각화 한 것을 Animation 이라고 한다.

실제로 SwiftUI에서 애니메이션을 적용하기는 매우 쉽습니다. 컴포넌트에 모디파이어로 애니메이션을 사용하겠다고 표시해주기만 하면 됩니다.

그러면 SwiftUI에서는 자동으로 상태 변화에 대한 차이를 계산해서 부드러운 전환효과를 적용해 줍니다.

애니메이션의 사용법

애니메이션을 적용한 간단한 코드입니다.

애니메이션을 적용하고자 하는 컴포넌트 코드 맨아래에 .animation() 모디파이어를 적용해주기만 하면 됩니다.

위 코드에서 애니메이션이 적용되는 컴포넌트는 Image만 적용되고 Button은 적용되지 않는 형태의 View가 될것입니다.

암묵적 애니메이션과 명시적 애니메이션

SwiftUI에서 애니메이션을 사용하는 방법은 크게 두가지 입니다.

암묵적인 방법명시적인 방법으로 나뉩니다.

암묵적인 애니메이션


암묵적인 방법은 위 코드에서 처럼 컴포넌트아래에 .animation모디파이어를 사용하는 것 입니다.

( ) 괄호안에는 애니메이션 옵션을 적용할 수 있습니다.

타이밍커브, 실행시간, 반복횟수를 애니메이션 옵션 이라고 하는데 아래에서 따로 다루겠습니다, 어떻게 사용하는지만 보고 넘어가세요 ㅎㅎ

명시적인 애니메이션

앞서 암묵적인 애니메이션코드를 살펴보고 한가지 문제점을 느끼셨나요?

바로 암목적인 방식을 사용하면 해당 컴포넌트에 상태가 여러개 변하는 상황에서 각각상태 변화에 대해서 애니메이션이 적용되지 않고 모두 동일한 애니메이션 효과가 적용됩니다.

특정 변화에 대해서는 애니메이션을 적용하고 싶지 않을 수도 있는데 암묵적으로 애니메이션을 사용하면 모든변화에 대해서 효과가 적용되겠죠?

예시

import SwiftUI
import Foundation

struct AnimationEx01: View {
    @State var circlePos: CGPoint = CGPoint(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2)
    @State var isSmall: Bool = false
    
    var body: some View {
        Circle()
            .frame(width: 100, height: 100)
            .position(circlePos)
            .scaleEffect(isSmall ? 1 : 2)
            .animation(Animation.linear(duration: 0.5))

        Button("move circle"){
            isSmall.toggle()
            circlePos = CGPoint(x: Int.random(in: 100...300),y: Int.random(in: 100...200))
        }
    }
}

예를들어 다음과 같이 원의 크기와 위치가 변화하는 코드가 있을때 위치변화하는 속도와 크기변화하는 속도를 따로 적용하고 싶다면 암묵적인 애니메이션은 도움이 되지 못할것입니다.

그럴 때를 위해서 명시적 애니메이션이 존재합니다.

다음과 같이 상태변화는 적용하는 코드에 작성하면 됩니다.

Button처럼 동작 코드를 클로저로 받는경우에 적용하고싶은 코드에 withAnimation클로저로 한번 더 묶어주기만 하면됩니다.

위 코드처럼 작성하면 위치변화에는 애니메이션이 적용되지만 색변화에 대해서는 효과가 적용되지 않겠죠?

애니메이션 옵션은 암묵적인 방법과 동일하게 적용하면 됩니다.

암묵적 애니메이션과 명시적 애니메이션의 비교

종류암묵적 애니메이션명시적 애니메이션
사용성간단함비교적 복잡함
형태모디파이어클로저

애니메이션 오버라이딩

앞서 명시적 애니메이션을 사용하는 이유가 애니메이션을 상태별로 다르게 적용하고 싶을때 사용한다고 했었죠?

그렇다면 예를들어 프로그래머가 실수로 명시적애니메이션을 적용했는데 모디파이어를 이용해서 암묵적으로도 다시한번 애니메이션을 적용하면 어떻게 될까요??

정답은 암묵적 애니메이션이 선택됩니다.

코드로 한번 살펴볼까요?

heart.fill이미지의 위치를 변화시키는 코드입니다. 여기서 다른건 애니메이션 전환속도입니다.

명시적애니메이션은 1, 암묵적 애니메이션은 0.3으로 설정되어있는데
결과는 0.3의 속도로 애니메이션이 적용될 것입니다.

실수로 이렇게 사용할 수도 있겠지만 만약 다른 컴포넌트의 duration은 1로 설정하고 하나만 빠르게 하고 싶다면 이렇게 사용하는것도 할 수 있겠죠

하지만 이런식으로 애니메이션을 오버라이딩 하면 코드의 가독성이 너무 떨어져 코드를 관리하기 어려워 질겁니다.

그럴때를 위해서 중첩 애니메이션이 존재합니다.

중첩 애니메이션

중첩애니메이션은 각 상태변화별로 애니메이션을 적용할때 권장되는 형태입니다.

위에서 처럼 오버라이딩을 하면 상황에 따라 다른 애니메이션이 적용되는 돌발성 애니메이션이 발생할 수 있습니다.

간단하게만 알아봅시다 형태는 아래와 같이 두가지 형태로 나뉠 수 있습니다.

(자세한 코드는 아래에서 다시 한번 보여드릴게요 😎)


위 코드처럼 모디파이어의 위치를 이용해서 적용할 효과 바로 아래에 .animation모디파이어를 작성할 수 있고,


또는 .animation모디파이어에 후행클로저를 이용해서 적용할 효과만 작성할 수 있습니다.

(애플에서 권장하는 형태는 이 형태이니 참고하세요 ㅎㅎ)

애니메이션 옵션

앞서 SwiftUI에서 애니메이션을 적용할때 타이밍커브, 실행시간, 반복횟수를 지정할 수 있다고 했었죠?

이 3가지 옵션이 무엇을 결정하는지 알아봅시다

타이밍 커브
(Timing Curve)
반복
(Repeat)
지연
(Duration)
애니메이션 속도변화애니메이션 반복횟수애니메이션 실행시간

반복이랑 지연은 어떤 옵션인지 아시겠죠?

반복에는 몇번 반복할것인지를 지정할 수 있고
지연에는 애니메이션이 동작하는 시간을 지정할 수 있습니다
타이밍커브에는 애니메이션 속도변화를 조절할 수 있습니다.

지연은 적은 값이 들어갈수록 빠르게 보이게 되겠죠?

여기서 타이밍 커브는 조금 생소할 수 있을거 같아 더 설명할게요

Timing Curve

타이밍커브는 애니메이션속도 변화를 조절할 수 있습니다.

EaseOut 는 일정하게 진행되다 끝에서 느려지는 효과
EaseIn 은 천천히 시작해서 일정하게 진행되는 효과
EaseInOut 는 처음과 끝부분이 느리게 진행되는 효과
Linear 는 애니메이션 도중에 속도 변화가 없는 속성입니다.

Ease효과를 이용하면 보다 안정적인 느낌의 애니메이션을 제공할 수 있습니다.
(코드로 적용하면서 어떤느낌인지 살펴보세요!)

Transition

애니메이션 효과를 트랜지션이라고 합니다.

트랜지션은 크게 3가지로 분리 할 수 있습니다.

  1. 형태/크기 변화
  2. 위치 변화
  3. 색/배경 변화

이렇게 3가지 효과를 적용할 수 있고 종류는 아래와 같습니다.

  • rotationEffect: 뷰를 2D 평면에서 회전시킵니다.


  • scaleEffect: 뷰의 크기를 확대하거나 축소합니다.


  • rotation3DEffect: 뷰를 3D 공간에서 회전시킵니다.

  • offset: 뷰를 특정 x, y 축 방향으로 이동시킵니다.


  • transformEffect: CGAffineTransform을 사용하여 뷰에 복합적인 변형을 적용합니다.

  • opacity: 뷰의 투명도를 조정합니다.


  • foregroundColor: 텍스트나 아이콘의 색상을 변경합니다.


  • background: 뷰의 배경색을 변경합니다.

  • cornerRadius: 둥근 모서리를 애니메이션으로 조정할 수 있습니다.

  • clipShape: 뷰를 특정 모양으로 자릅니다.

  • border: 테두리 두께와 색상을 변경합니다.
  • frame: 뷰의 크기와 위치를 변경합니다.

  • padding: 내부 여백을 조정합니다.
  • shadow: 그림자의 크기와 투명도를 조정합니다.

  • blur: 블러 효과를 추가합니다.

  • hueRotation: 색조를 회전시킵니다.

  • brightness: 밝기를 조정합니다.

  • contrast: 대비를 조정합니다.

  • saturation: 채도를 조정합니다.

모든 모디파이어를 소개할수는 없으니 종류만 살펴보고 애플 공식문서나 gpt를 활용하세요!

마무리

SwiftUI에서는 뷰의 전환효과를 줄 수 있는데 이를 Animation이라고 한다.

애니메이션을 적용하는 방법은 명시적인 방법과 암묵적인 방법 두가지로 나눌 수 있다.

명시적인 방법과 암묵적인 방법을 동시에 사용할 수 있고 상태별로 다른 애니메이션을 적용할 수 있는데 이를 애니메이션 오버라이딩이라고 한다.

애니메이션 효과를 transition이라고 하고 형태/크기 변화, 위치 변화, 색/배경 변화에 대해서 다양한 효과를 적용할 수 있다.

출처

https://www.youtube.com/watch?v=IuSuHJs5-KE&t=22s

profile
iOS Developer, 천 리 길도 한 걸음부터

0개의 댓글