- Total
꿈꾸는리버리
[Animation 뚜까파기 1] Animation의 기초 본문
해당 블로그는 KWDC에서 Pavel Zak님의 강연을 듣고 너무 감명을 받아서 시작하게 된 ... 애니메이션 공부..!
자세한 내용은 아래 참고 ...!
Animation 뚜까파기 모음 zip
2. Animation을 일어나게 하는 Trigger들 ( Gesture를 중심으로 )
+) Animation을 위한 미니 공부들
Position vs Offset 예시와 함께 비교 분석하기
🔮 Animation의 기본 원리
아래 그림과 같이 기본적으로 기존의 A라는 상태에서 B라는 상태로 갈 때 Animation을 넣는다.
아래의 gif를 보자. frame의 세로 크기를 100 <-> 400로 변경하는 코드이다.
왼쪽의 경우에는 Animation이 없는 기본 모습이고, 오른쪽은 Animation이 있는 모습이다.
딱 코드 2줄을 추가했는데, status가 바꼈을 때 좀 더 스무스하게 뷰가 그려지는 것을 확인할 수 있다.
Rectangle()
// 애니메이션 값이 on, off 될 때마다 변경되는 frame의 크기
.frame(width: 300, height: change ? 100 : 400)
.foregroundColor(.blue)
// 애니메이션을 넣겠다고 하는 부분
.animation(.default, value: change)
🔮 Animation Timing Curves
앞서 살펴봤던 Instance method에서 Animation 부분을 보자. 이 Animation의 자리에는 다음과 같이 .default( 지금은 .easyInOut임 ), .linear, .easyIn 등이 들어갈 수 있다.
spring animations이나 custom animation, delay 등 다양한 Animation 속성들이 있지만 그건 뒤에 공부해보도록 하고 우선은 기본적인 4개의 Animation을 먼저 보려 한다.
그림에 나와있는 거는 Animation의 속력이다. 옆 영상을 보면 .easyInOut의 경우, 공의 속도가 느렸다가 빨라졌다가 다시 느려지는 것을 알 수 있다.
+) 나는 조금 헷갈렸어서 외울 때 나는 외국인들이 흥분하면 침착하라고 "Take easy"라고 해서.. easy가 천천히 ~~ 라는 느낌으로 기억했고 그래서 "easyIn == 처음 들어갈 때 침착한다" 이런식으로 기억했다 ㅋㅋ... ( 머쓱 )
🔮 Animation을 넣을 수 있는 Value
Animation을 넣을 수 있는 value는 number를 가지고 있는 속성값이면 왠만해서 다 되는 것 같았다.
ex) offset, color, position, rotationEffect, frame 등등
이거는 그냥 코드만 남겨두겠습니다. 코드 복붙해서 xcode에서 작업하면서 알아보시는 게 좋을 것 같아요!
struct AnimationView: View {
@State private var change = false
var body: some View {
VStack(spacing: 0) {
Button {
change.toggle()
} label: {
Text("버튼 클릭!")
}
.padding(.vertical, 50)
ScrollView(showsIndicators: false) {
VStack(spacing: 50) {
VStack(spacing: 20) {
Text("1) offset")
.foregroundStyle(.black)
Rectangle()
.frame(width: 300, height: 100)
// x+가 오른쪽, y+가 아래쪽
.offset(x: 0, y: change ? 20 : 0 )
}
VStack(spacing: 20) {
Text("2) frame")
.foregroundStyle(.black)
Rectangle()
// 위 아래 컴포넌트도 같이 움직임
.frame(width: 300, height: change ? 10 : 100)
}
VStack(spacing: 20) {
Text("3) rotationEffect")
.foregroundStyle(.black)
Rectangle()
// 기준점이 anctor
.rotationEffect(Angle.degrees(change ? 220 : 0), anchor: .bottomTrailing)
.frame(width: 300, height: 100)
}
VStack(spacing: 20) {
Text("4) scaleEffect")
.foregroundStyle(.black)
Rectangle()
// frame과 달리 다른 view에는 영향을 안 줌
.scaleEffect(change ? 0.5 : 1)
.frame(width: 300, height: 100)
}
VStack(spacing: 20) {
Text("5) cornerRadius")
.foregroundStyle(.black)
Rectangle()
.clipShape(RoundedCorner(cornerRadius: change ? 30 : 0))
.frame(width: 300, height: 100)
}
VStack(spacing: 20) {
Text("6) fontSize")
.foregroundStyle(.black)
Text("Hello, Animation")
.font(change ? .caption2 : .title)
Text("Hello, Animation")
.font(.title)
// .font에서 animation 변경하는 거랑 달리 다른 view에는 영향을 안 줌
.scaleEffect(change ? 0.4 : 1)
}
VStack(spacing: 20) {
Text("7) Grid")
Grid {
GridRow {
Rectangle()
.frame(width: 100, height: 100)
if !change {
Rectangle()
.frame(width: 100, height: 100)
Rectangle()
.frame(width: 100, height: 100)
}
}
}
}
}
.padding(.bottom, 100)
}
}
// 이거를 제일 먼저 꼭 추가해줘야 함 !
.animation(.default, value: change)
.foregroundColor(.blue)
}
}
🔮 Animation을 추가할 수 있는 방법 3가지
isExpanded 상태가 변경될 때 전체 뷰 계층에 애니메이션을 적용하는 방법
- 이 버튼을 클릭하면 뷰 전체가 자연스럽게 움직이는 것을 볼 수 있다.
isExpanded 상태가 변경될 때, Rectangle에만 애니메이션을 적용하는 방법
- 이 버튼을 클릭하면 하단의 Rectangle만 자연스럽게 움직이는 것을 볼 수 있다.
3️⃣ animation(_:)
binding 값이 바뀔 때마다 애니메이션 발생
- 아래 슬라이드를 움직이면 자연스럽게 아래의 Ractangle이 움직이는 것을 알 수 있다.
struct AnimationExample: View {
@State private var isExpanded = false
@State private var scale: CGFloat = 1.0
var body: some View {
VStack {
// 1️⃣
Button("1️. Toggle Size") {
withAnimation(.easeInOut(duration: 0.5)) {
isExpanded.toggle()
}
}
Rectangle()
.frame(width: isExpanded ? 200 : 100, height: isExpanded ? 200 : 100)
.foregroundColor(.blue)
.padding(.bottom, 50)
// 2️⃣
Button("2️. Toggle Size") {
isExpanded.toggle()
}
Rectangle()
.frame(width: isExpanded ? 200 : 100, height: isExpanded ? 200 : 100)
.foregroundColor(.blue)
.animation(.easeInOut(duration: 0.5), value: isExpanded)
.padding(.bottom, 50)
// 3️⃣
Text("3) Binding scale")
Slider(value: $scale.animation(.spring()), in: 0.5...1.0)
.padding()
Rectangle()
.foregroundColor(.blue)
.scaleEffect(scale)
}
.padding(.top, 50)
}
}
출처
'오뚝이 개발자 > SwiftUI' 카테고리의 다른 글
Position vs Offset 예시와 함께 비교 분석하기 (0) | 2024.11.25 |
---|---|
[인앱 결제하기 4] 구독 결제 구현하기 (7) | 2024.10.20 |
[Error] SPM 설치 중 체크박스가 누락 -> 수동 삭제하기 (4) | 2024.10.04 |
[iCloudKit 시리즈 4] 나도 백엔드 있다 - iCloud Noti 알아보기 (1) | 2024.10.01 |
[iCloudKit 시리즈 3] 나도 백엔드 있다 - Coredata -> iCloud로 변경하기 (0) | 2024.10.01 |