diff --git a/Docs/Reference.md b/Docs/Reference.md index eb91642..e7fbfff 100644 --- a/Docs/Reference.md +++ b/Docs/Reference.md @@ -53,6 +53,41 @@ Drawer(heights: [100, 340]) { }.impact(.light) ``` +### Dislodge + +#### 👆 `dislodge(_: UIImpactFeedbackGenerator.FeedbackStyle) -> Drawer` + +Sets the haptic impact of the drawer when dislodging from rest. + +**Feedback Style** +Choose from the possible impact styles. [Apple Docs](https://developer.apple.com/documentation/uikit/uiimpactfeedbackgenerator/feedbackstyle) +```swift +public enum FeedbackStyle : Int { + + /// A collision between small, light user interface elements. + case light = 0 + + /// A collision between moderately sized user interface elements. + case medium = 1 + + /// A collision between large, heavy user interface elements. + case heavy = 2 + + @available(iOS 13.0, *) + case soft = 3 + + @available(iOS 13.0, *) + case rigid = 4 +} +``` + +**Usage** +```swift +Drawer(heights: [100, 340]) { + Color.blue +}.dislodge(.light) +``` + ### Spring #### 🪀 `spring(_: CGFloat) -> Drawer` diff --git a/Sources/Drawer/Drawer+Drag.swift b/Sources/Drawer/Drawer+Drag.swift index dbe39c2..3a2934d 100644 --- a/Sources/Drawer/Drawer+Drag.swift +++ b/Sources/Drawer/Drawer+Drag.swift @@ -20,6 +20,12 @@ internal extension Drawer { } func dragChanged(_ value: DragGesture.Value) { + if dragging == false { + DispatchQueue.main.async { + self.dislodgeGenerator?.impactOccurred() + } + } + dragging = true height = Drawer.dampen( diff --git a/Sources/Drawer/Drawer+Modifiers.swift b/Sources/Drawer/Drawer+Modifiers.swift index e19b374..9365402 100644 --- a/Sources/Drawer/Drawer+Modifiers.swift +++ b/Sources/Drawer/Drawer+Modifiers.swift @@ -21,6 +21,7 @@ public extension Drawer { didRest: didRest, didLayoutForSizeClass: didLayoutForSizeClass, impactGenerator: impactGenerator, + dislodgeGenerator: dislodgeGenerator, content: content) } @@ -36,6 +37,7 @@ public extension Drawer { didRest: didRest, didLayoutForSizeClass: didLayoutForSizeClass, impactGenerator: impactGenerator, + dislodgeGenerator: dislodgeGenerator, content: content) } @@ -52,6 +54,24 @@ public extension Drawer { didRest: didRest, didLayoutForSizeClass: didLayoutForSizeClass, impactGenerator: impactGenerator, + dislodgeGenerator: dislodgeGenerator, + content: content) + } + + /// Sets the haptic feedback of dislodging the drawer + /// - Parameter dislodge: `FeedbackStyle` for dislodge level + /// - Returns: Drawer with specified dislodge level + func dislodge(_ dislodge: UIImpactFeedbackGenerator.FeedbackStyle) -> Drawer { + let dislodgeGenerator = UIImpactFeedbackGenerator(style: dislodge) + return Drawer( + heights: $heights, + height: height, + restingHeight: restingHeight, + springHeight: springHeight, + didRest: didRest, + didLayoutForSizeClass: didLayoutForSizeClass, + impactGenerator: impactGenerator, + dislodgeGenerator: dislodgeGenerator, content: content) } @@ -67,6 +87,7 @@ public extension Drawer { didRest: didRest, didLayoutForSizeClass: didLayoutForSizeClass, impactGenerator: impactGenerator, + dislodgeGenerator: dislodgeGenerator, content: content) } @@ -83,6 +104,7 @@ public extension Drawer { didRest: didRest, didLayoutForSizeClass: didLayoutForSizeClass, impactGenerator: impactGenerator, + dislodgeGenerator: dislodgeGenerator, content: content) } } diff --git a/Sources/Drawer/Drawer.swift b/Sources/Drawer/Drawer.swift index f06c3ad..e9deec0 100644 --- a/Sources/Drawer/Drawer.swift +++ b/Sources/Drawer/Drawer.swift @@ -60,6 +60,7 @@ public struct Drawer: View where Content: View { // MARK: Haptics internal var impactGenerator: UIImpactFeedbackGenerator? + internal var dislodgeGenerator: UIImpactFeedbackGenerator? // MARK: View @@ -98,6 +99,7 @@ internal extension Drawer { didRest: ((_ height: CGFloat) -> ())?, didLayoutForSizeClass: ((SizeClass) -> ())?, impactGenerator: UIImpactFeedbackGenerator?, + dislodgeGenerator: UIImpactFeedbackGenerator?, content: Content ) { self._heights = heights @@ -108,6 +110,7 @@ internal extension Drawer { self.didLayoutForSizeClass = didLayoutForSizeClass self.content = content self.impactGenerator = impactGenerator + self.dislodgeGenerator = dislodgeGenerator } }