본문 바로가기
💻 Development/SwiftUI

[SwiftUI] withAnimation VS .animation

by Claudia 끌라우 2023. 8. 2.
반응형

* 공부했던 내용을 주관적으로 해석하여 '제가' 이해하기 쉽도록 작성하였습니다. 잘못된 정보가 있을 시 알려주시면 제게 큰 힘이 됩니다!

- 상태가 변동될 때 갑작 스러운 변화를 느껴 사용자가 어색함을 느끼지 않기 위해 부드러운 변화를 만들어줌

 

문서 링크 : https://developer.apple.com/documentation/swiftui/animations


[ OverView ]

애니메이션의 종류

  • withAnimation(_:_:)
  • animation(_:value:)
  • Binding을 활용한 animation(_:)

 


 

  withAnimation(_:_:)  

기본 설명 :

제공된 애니메이션으로 뷰 본문을 다시 계산한 결과를 반환한다

(Returns the result of recomputing the view’s body with the provided animation.)

 

Discussion

This function sets the given Animation as the animation property of the thread’s current Transaction.

 

- 특정 값이 변화할 때(eg. false -> ture) 애니메이션 가능

- 변하는 상태 시점을 잡아서 그 시점에 애니메이션을 넣어줌(with이 들어가는 이유)

- 여러 객체를 동시에 다룰 수 있다.

 

// 예시 1 : withAnimation을 사용했을 때
import SwiftUI

struct ContentView: View {
    
    @State var isanimated: Bool = false //Bool -> ture or false
    
    var body: some View {
        
        VStack {
            Button("Button") {
                withAnimation(.default) {     //defeult는 fade 효과임
                    isanimated.toggle()
                }

            }
            
            Spacer()
            
            RoundedRectangle(cornerRadius: isanimated ? 50 : 25)
            //해석 : cornerRadius바꿀건데 isanimated가 true니? true일때 50, false일때 25를 해줭
                .fill(isanimated ? Color.yellow : Color.green)
                .frame(
                    width: isanimated ? 100 : 300,
                    height: isanimated ? 100 : 300)
                .rotationEffect(Angle(degrees: isanimated ? 360 : 0))
            
            Rectangle()
                .frame(height: 10)
            
            RoundedRectangle(cornerRadius: isanimated ? 50 : 25)
                .fill(isanimated ? Color.red : Color.gray)
                .frame(
                    width: isanimated ? 100 : 300,
                    height: isanimated ? 100 : 300)
                .rotationEffect(Angle(degrees: isanimated ? 360 : 0))
        }
    }
}

버튼이 있고

-> 버튼은 withAnimation 변수를 불러오고

-> withAnimation에 영향을 받는것들은 isAnimated.toggle()

 

withAnimation에서 toggle되어서 isanimated를 가지고 있는 녀석들이 전부 바뀜

  animation(_:value:)  

기본 설명 : 

지정된 값이 변경되면 지정된 애니메이션을 이 뷰에 적용합니다.

Applies the given animation to this view when the specified value changes.

 

animation -> modifier(수정자)임!

Parameters

animation

The animation to apply. If animation is nil, the view doesn’t animate.

 

value

A value to monitor for changes.

Return Value

A view that applies animation to this view whenever value changes.

 

- 객체 자체에 애니메이션을 걸어서 그 객체가 애니메이션을 할 수 있도록 해줌.

- 하나하나에 애니메니션을 거는 방식.

- 여러 객체를 하나의 변수로 움직이게 하려면 withAnimation을 사용해야한다.

 

// 예시 2 : withAnimation이 빠지고 버튼은 그저 토글만,, 그리고 2번 사각형에 .animation modifier만 붙임
import SwiftUI

struct ContentView: View {
    
    @State var isanimated: Bool = false //Bool -> ture or false
    
    var body: some View {
        
        VStack {
            Button("Button") {
                    isanimated.toggle() // 1. withAnimation없이 토글만함
                  }
            }
            
            Spacer()
            
            RoundedRectangle(cornerRadius: isanimated ? 50 : 25)
            //해석 예시 : cornerRadius바꿀건데 isanimated가 true니? true일때 50, false일때 25를 해줭
                .fill(isanimated ? Color.yellow : Color.green)
                .frame(
                    width: isanimated ? 100 : 300,
                    height: isanimated ? 100 : 300)
                .rotationEffect(Angle(degrees: isanimated ? 360 : 0))
                //여긴 .animation이 없다
            
            Rectangle()
                .frame(height: 10)
            
            RoundedRectangle(cornerRadius: isanimated ? 50 : 25)
                .fill(isanimated ? Color.red : Color.gray)
                .frame(
                    width: isanimated ? 100 : 300,
                    height: isanimated ? 100 : 300)
                .rotationEffect(Angle(degrees: isanimated ? 360 : 0))
                .animation( // 2. 요기 주목!!!! 여긴있지롱
                    Animation
                    .default
                    , value: isAnimated
                )
        }
    }
}
1번엔 애니메이션이 안먹혔다. 왜냐 2번 사각형만 .animation 수정자를 넣었기때문

// 예시3 : State변수를 따로 지정해서 애니메이션을 했을 때
// 1번 사각형은 .animation이 없고 2번은 있다. 
// 이렇게 되면 어떻게 될지 생각해 보렴 미래의 끌라우야 ^^

import SwiftUI

struct ContentView: View {
    
    @State var isAnimated1: Bool = false
    @State var isAnimated2: Bool = false
    
    
    var body: some View {
        
        VStack {
            Button("Button") {

                withAnimation(.default) {     //defeult는 fade 효과
                    isAnimated1.toggle()
                    isAnimated2.toggle()
                } // withAnimation(.어떻게 움직일건지){어디에 무슨 영향을 줄건지?}

            }
            
            Spacer()
            
            RoundedRectangle(cornerRadius: isAnimated1 ? 50 : 25)
                .fill(isAnimated1 ? Color.yellow : Color.green)
                .frame(
                    width: isAnimated1 ? 100 : 300,
                    height: isAnimated1 ? 100 : 300)
                .rotationEffect(Angle(degrees: isAnimated1 ? 360 : 0))
            
            
            Rectangle() //구분선
                .frame(height: 10)
            
            RoundedRectangle(cornerRadius: isAnimated2 ? 50 : 25)
                .fill(isAnimated2 ? Color.red : Color.gray)
                .frame(
                    width: isAnimated2 ? 100 : 300,
                    height: isAnimated2 ? 100 : 300)
                .rotationEffect(Angle(degrees: isAnimated2 ? 360 : 0))
                .animation(
                      Animation
                      .default
                      , value: isAnimated2
                  )
        }
    }
}

  animation(_:)  

기본설명 :

바인딩 값이 변경될 때 수행할 애니메이션을 지정합니다.

(Specifies an animation to perform when the binding value changes.)

 

- 이거슨.. 아직 안배움... 이해못함...^^

 


2023 / 07 / 23 - 개발 이슈

- TutorialView작업할 때, 

   StartingView에서 TutorialView로 넘어갈시, TutorialView 내부의 TabView가 덜컹거렸음..!

   .animation을 수정하니까 고쳐짐! 

// 변경 전

import SwiftUI

struct ContentView: View {
    @State private var pageNum = 1
    var body: some View {
        TabView(selection: $pageNum) {
            FirstOnBoardingView(pageNum: $pageNum)
                .tag(1)
            SecondOnBoardingView(pageNum: $pageNum)
                .tag(2)
            ThirdOnBoardingView()
                .tag(3)
            
        }
        
        .transition(.slide)
        .tabViewStyle(.page(indexDisplayMode: .never))
        .navigationBarHidden(true)
        .animation(Animation.easeInOut) // <- 이 부분
    }
}
변경 전

에러 이유

- 기존의 .animation은 iOS 15.0이후로 사라졌다고 한다. 하지만 XCode상에서는 아직까지 되는 모습을 확인할 수 있음.

   But, 오류 투성이라 withAnimation 혹은 animation(_:value:)를 대신 사용하기를 권고하고 있다.


// 변경 후

import SwiftUI

struct ContentView: View {
    @State private var pageNum = 1
    var body: some View {
        TabView(selection: $pageNum) {
            FirstOnBoardingView(pageNum: $pageNum)
                .tag(1)
            SecondOnBoardingView(pageNum: $pageNum)
                .tag(2)
            ThirdOnBoardingView()
                .tag(3)
            
        }
        .animation(.easeInOut, value: pageNum) // <- 이부분
        .transition(.slide)
        .tabViewStyle(.page(indexDisplayMode: .never))
        .navigationBarHidden(true)
    }
}
변경 후

 

 

 

 

 

 

반응형

댓글