@@ -6,27 +6,28 @@ struct CouponCreationSuccess: View {
66 let couponCode : String
77 let shareMessage : String
88 let onDismiss : ( ) -> Void
9- @State private var showingShareSheet : Bool = false
109
10+ @State private var showingShareSheet : Bool = false
11+ @State private var imageScale = Constants . initialImageScale
12+ @State private var imageBottomSpace = Constants . initialImageBottomSpacing
13+ @State private var textOpacity = Constants . initialTextOpacity
14+ @State private var buttonsVerticalOffset = Constants . initialButtonsVerticalOffset
1115
1216 var body : some View {
1317 VStack ( alignment: . center, spacing: 0 ) {
14- // Anchor the action sheet at the top to be able to show the popover on iPad in the most appropriate position
15- Divider ( )
16- . shareSheet ( isPresented: $showingShareSheet) {
17- ShareSheet ( activityItems: [ shareMessage] )
18- }
19-
2018 Spacer ( )
2119
2220 VStack ( alignment: . leading, spacing: 0 ) {
2321 Image ( uiImage: UIImage . checkSuccessImage)
24- . padding ( . bottom, Constants . imageBottomSpacing)
22+ . padding ( . bottom, imageBottomSpace)
23+ . scaleEffect ( imageScale)
2524 Text ( Localization . successMessage)
2625 . font ( . largeTitle)
2726 . bold ( )
27+ . opacity ( textOpacity)
2828 Text ( couponCode)
2929 . font ( . largeTitle)
30+ . opacity ( textOpacity)
3031 }
3132 . padding ( Constants . contentPadding)
3233
@@ -38,21 +39,73 @@ struct CouponCreationSuccess: View {
3839 // TODO: add analytics
3940 }
4041 . buttonStyle ( PrimaryButtonStyle ( ) )
42+ . shareSheet ( isPresented: $showingShareSheet) {
43+ ShareSheet ( activityItems: [ shareMessage] )
44+ }
4145
4246 Button ( Localization . close) {
4347 onDismiss ( )
4448 }
4549 . buttonStyle ( SecondaryButtonStyle ( ) )
4650 }
4751 . padding ( Constants . contentPadding)
52+ . offset ( x: 0 , y: buttonsVerticalOffset)
53+ }
54+ . onAppear {
55+ animateEntry ( )
56+ }
57+ }
58+
59+ func animateEntry( ) {
60+ let buttonGroupAnimation = Animation . easeIn ( duration: Constants . buttonGroupAnimationDuration)
61+
62+ let imageAnimation = Animation
63+ . interpolatingSpring ( stiffness: Constants . imageAnimationStiffness,
64+ damping: Constants . imageAnimationDamping,
65+ initialVelocity: Constants . imageAnimationInitialVelocity)
66+ . delay ( Constants . imageAnimationDelay)
67+
68+ let textAnimation = Animation
69+ . easeIn ( duration: Constants . textAnimationDuration)
70+ . delay ( Constants . textAnimationDelay)
71+
72+ withAnimation ( buttonGroupAnimation) {
73+ buttonsVerticalOffset = Constants . finalButtonsVerticalOffset
74+ }
75+
76+ withAnimation ( imageAnimation) {
77+ imageScale = Constants . finalImageScale
78+ }
79+
80+ withAnimation ( textAnimation) {
81+ imageBottomSpace = Constants . finalImageBottomSpacing
82+ textOpacity = Constants . finalTextOpacity
4883 }
4984 }
5085}
5186
5287private extension CouponCreationSuccess {
5388 enum Constants {
54- static let imageBottomSpacing : CGFloat = 40
5589 static let contentPadding : CGFloat = 16
90+
91+ static let initialImageBottomSpacing : CGFloat = 80
92+ static let finalImageBottomSpacing : CGFloat = 40
93+ static let initialImageScale : CGFloat = 0
94+ static let finalImageScale : CGFloat = 1
95+
96+ static let initialTextOpacity : CGFloat = 0
97+ static let finalTextOpacity : CGFloat = 1
98+
99+ static let initialButtonsVerticalOffset : CGFloat = 300
100+ static let finalButtonsVerticalOffset : CGFloat = 0
101+
102+ static let buttonGroupAnimationDuration : CGFloat = 0.3
103+ static let imageAnimationStiffness : CGFloat = 150
104+ static let imageAnimationDamping : CGFloat = 15
105+ static let imageAnimationInitialVelocity : CGFloat = 3
106+ static let imageAnimationDelay : CGFloat = 0.7
107+ static let textAnimationDuration : CGFloat = 0.3
108+ static let textAnimationDelay : CGFloat = 0.5
56109 }
57110
58111 enum Localization {
0 commit comments