Created
October 22, 2023 15:02
-
-
Save mdb1/4680d796b91c370eb07ba6f6da1d6775 to your computer and use it in GitHub Desktop.
TapShrinkModifier
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
extension View { | |
/// Adds the `TapShrinkModifier` modifier. | |
/// A modifier that adds a shrink animation on tap. | |
/// - Parameters: | |
/// - animationDuration: The shrink animation duration. `Default = 0.3`. | |
/// - shrinkScale: The scale value for when the view is pressed. `Default = 0.85`. | |
/// - defaultScale: The scale value for when the view is not pressed: `Default = 1.0`. | |
/// - action: The action to execute. | |
/// - Returns: The original view, with the modifier applied. | |
func shrinkOnTap( | |
animationDuration: TimeInterval = 0.3, | |
shrinkScale: CGFloat = 0.85, | |
defaultScale: CGFloat = 1, | |
action: @escaping () -> Void | |
) -> some View { | |
modifier( | |
TapShrinkModifier( | |
animationDuration: animationDuration, | |
shrinkScale: shrinkScale, | |
defaultScale: defaultScale, | |
action: action | |
) | |
) | |
} | |
} | |
struct TapShrinkModifier: ViewModifier { | |
@State private var isTouched = false | |
private var animationDuration: TimeInterval | |
private var shrinkScale: CGFloat | |
private var defaultScale: CGFloat | |
private var action: () -> Void | |
init( | |
animationDuration: TimeInterval, | |
shrinkScale: CGFloat, | |
defaultScale: CGFloat, | |
action: @escaping () -> Void | |
) { | |
self.animationDuration = animationDuration | |
self.shrinkScale = shrinkScale | |
self.defaultScale = defaultScale | |
self.action = action | |
} | |
func body(content: Content) -> some View { | |
content | |
.scaleEffect(isTouched ? shrinkScale : defaultScale, anchor: .center) | |
.animation(.easeInOut(duration: animationDuration), value: isTouched) | |
.gesture( | |
DragGesture(minimumDistance: 0) | |
.onChanged { _ in isTouched = true } | |
.onEnded { _ in | |
isTouched = false | |
action() | |
} | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment