Skip to content

Commit

Permalink
fix: 🐛 Add touch area in FioriButton to support cancel action
Browse files Browse the repository at this point in the history
  • Loading branch information
billzhou0223 committed Apr 7, 2022
1 parent 669e057 commit 61d35c0
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ struct CustomFioriButtonStyle: FioriButtonStyle {
return configuration.label
.foregroundColor(.white)
.padding(50)
.frame(width: 500)
.background(Circle().fill(color))
}
}
Expand Down
52 changes: 47 additions & 5 deletions Sources/FioriSwiftUICore/FioriButton/FioriButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public struct FioriButton<Label: View>: View {
let action: ((UIControl.State) -> Void)?
let label: (UIControl.State) -> Label
let isSelectionPersistent: Bool
private let touchAreaInset: CGFloat = 50

@Environment(\.isEnabled) private var isEnabled
@Environment(\.fioriButtonStyle) private var fioriButtonStyle
Expand Down Expand Up @@ -94,24 +95,65 @@ public struct FioriButton<Label: View>: View {
return ZStack {
self.fioriButtonStyle.makeBody(configuration: config)
}
.gesture(createGesture())
.overlay(GeometryReader { proxy in
Color.clear.contentShape(Rectangle()).gesture(createGesture(proxy.size))
})
}

func createGesture() -> some Gesture {
func createGesture(_ size: CGSize) -> some Gesture {
let touchArea = CGRect(origin: .zero, size: size).insetBy(dx: -self.touchAreaInset, dy: -self.touchAreaInset)
var isCancelled = false

if self.isSelectionPersistent {
return DragGesture(minimumDistance: 0)
.onChanged { _ in
.onChanged { value in
guard !isCancelled else {
return
}

if !touchArea.contains(value.location) {
isCancelled = true
}
}
.onEnded { _ in
defer {
isCancelled = false
}

guard !isCancelled else {
return
}

self._state = self.state == .normal ? .selected : .normal
self.action?(state)
}
} else {
return DragGesture(minimumDistance: 0)
.onChanged { _ in
self._state = .highlighted
.onChanged { value in
guard !isCancelled else {
return
}

if !touchArea.contains(value.location) {
isCancelled = true
self._state = .normal

return
}

if self._state == .normal {
self._state = .highlighted
}
}
.onEnded { _ in
defer {
isCancelled = false
}

guard !isCancelled else {
return
}

self._state = .normal
self.action?(state)
}
Expand Down

0 comments on commit 61d35c0

Please sign in to comment.