/
FlipAndSlideAnimationPlusTransition.swift
109 lines (95 loc) · 2.84 KB
/
FlipAndSlideAnimationPlusTransition.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//
// FlipAndSlideView.swift
// SwiftUIPlayground
//
// Created by Raheel Ahmad on 5/9/22.
//
import SwiftUI
struct CardViewWithAnimation: View {
let card: Card
let side: Card.Side
func sideView(side: Card.Side) -> some View {
ZStack {
VStack(alignment: .leading) {
HStack {
Text(side.text.capitalized)
.font(.callout.smallCaps().bold())
.foregroundColor(side.foreground).opacity(0.6)
Spacer()
}
.padding(.horizontal, 20)
Spacer()
}
Text(card.text(side: side))
.font(.title3)
.foregroundColor(side.foreground).opacity(0.9)
.lineSpacing(2.4)
.padding(.horizontal, 20)
}
.padding(.vertical)
.background(
RoundedRectangle(cornerRadius: 12, style: .continuous)
.fill(side.background)
)
}
var body: some View {
ZStack {
sideView(side: .front)
.rotation3DEffect(.degrees(side == .front ? 0 : 180), axis: (0, 1, 0))
.opacity(side == .front ? 1 : 0)
sideView(side: .back)
.rotation3DEffect(.degrees(side == .back ? 0 : -180), axis: (0, 1, 0))
.opacity(side == .back ? 1 : 0)
}
}
}
struct FlipAndSlideAnimationPlusTransition: View {
let cards: [Card]
@State var side: Card.Side = .front
@State private var index = 0
var card: Card {
cards[index]
}
var transition: AnyTransition {
.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading))
}
var animation: Animation {
.easeInOut(duration: 0.8)
}
var flip: some View {
Button {
withAnimation(animation) {
side = .back
}
} label: {
Image(systemName: "arrow.triangle.swap")
.resizable()
.frame(width: 24, height: 24)
}
}
var body: some View {
VStack {
CardViewWithAnimation(card: card, side: side)
.id(card.id)
.onTapGesture {
if side == .front {
withAnimation(animation) {
side = .back
}
}
}
.padding()
.transition(transition)
VStack {
if side == .back {
Navigation(index: $index, side: $side, count: cards.count)
}
}.frame(height: 64)
}
}
}
struct FlipAndSlideView_Previews: PreviewProvider {
static var previews: some View {
FlipAndSlideAnimationPlusTransition(cards: sampleCards)
}
}