Skip to content

Instantly share code, notes, and snippets.

@mdb1
Created October 22, 2023 15:04
Show Gist options
  • Save mdb1/85215950d5066dcd3c320a39eae0be7c to your computer and use it in GitHub Desktop.
Save mdb1/85215950d5066dcd3c320a39eae0be7c to your computer and use it in GitHub Desktop.
LongPressShrinkModifier
import SwiftUI
extension View {
/// Adds the `LongPressShrinkModifier` modifier.
/// A modifier that adds a LongPressGesture action, that shrinks the view while it's being tapped.
/// - 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`.
/// - minimumLongPressDuration: The minimum long press duration. `Default = 0.5`.
/// - action: The action to execute.
/// - Returns: The original view, with the modifier applied.
func shrinkOnLongPress(
animationDuration: TimeInterval = 0.3,
shrinkScale: CGFloat = 0.85,
defaultScale: CGFloat = 1,
minimumLongPressDuration: TimeInterval = 0.5,
action: @escaping () -> Void
) -> some View {
modifier(
LongPressShrinkModifier(
animationDuration: animationDuration,
shrinkScale: shrinkScale,
defaultScale: defaultScale,
minimumLongPressDuration: minimumLongPressDuration,
action: action
)
)
}
}
struct LongPressShrinkModifier: ViewModifier {
@State private var isTouched = false
private var animationDuration: TimeInterval
private var shrinkScale: CGFloat
private var defaultScale: CGFloat
private var minimumLongPressDuration: TimeInterval
private var action: () -> Void
init(
animationDuration: TimeInterval,
shrinkScale: CGFloat,
defaultScale: CGFloat,
minimumLongPressDuration: TimeInterval,
action: @escaping () -> Void
) {
self.animationDuration = animationDuration
self.shrinkScale = shrinkScale
self.defaultScale = defaultScale
self.minimumLongPressDuration = minimumLongPressDuration
self.action = action
}
func body(content: Content) -> some View {
content
.scaleEffect(isTouched ? shrinkScale : defaultScale, anchor: .center)
.animation(.easeInOut(duration: animationDuration), value: isTouched)
.onLongPressGesture(
minimumDuration: minimumLongPressDuration,
pressing: { pressing in
isTouched = pressing
}, perform: {
action()
}
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment