- Use longpress gesture to implement pannable tap gesture, e.g. slide between actions, select whichever one is below on touchup
- Remove swipe to dismiss, in line with System Action sheet
pull/1/head
Michael Kirk 6 years ago
parent 6539318b42
commit e5e5bbddc9

@ -71,10 +71,6 @@ class MenuActionsViewController: UIViewController, MenuActionSheetDelegate {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapBackground))
self.view.addGestureRecognizer(tapGesture)
let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(didSwipeBackground))
swipeGesture.direction = .down
self.view.addGestureRecognizer(swipeGesture)
}
override func viewDidAppear(_ animated: Bool) {
@ -249,11 +245,6 @@ class MenuActionsViewController: UIViewController, MenuActionSheetDelegate {
animateDismiss(action: nil)
}
@objc
func didSwipeBackground(gesture: UISwipeGestureRecognizer) {
animateDismiss(action: nil)
}
// MARK: MenuActionSheetDelegate
func actionSheet(_ actionSheet: MenuActionSheetView, didSelectAction action: MenuAction) {
@ -269,6 +260,7 @@ class MenuActionSheetView: UIView, MenuActionViewDelegate {
private let actionStackView: UIStackView
private var actions: [MenuAction]
private var actionViews: [MenuActionView]
weak var delegate: MenuActionSheetDelegate?
override var bounds: CGRect {
@ -288,29 +280,57 @@ class MenuActionSheetView: UIView, MenuActionViewDelegate {
actionStackView.spacing = CGHairlineWidth()
actions = []
actionViews = []
super.init(frame: frame)
backgroundColor = UIColor.ows_light10
addSubview(actionStackView)
actionStackView.ows_autoPinToSuperviewEdges()
actionStackView.autoPinEdgesToSuperviewEdges()
self.clipsToBounds = true
// Prevent panning from percolating to the superview, which would
// cause us to dismiss
let panGestureSink = UIPanGestureRecognizer(target: nil, action: nil)
self.addGestureRecognizer(panGestureSink)
let touchGesture = UILongPressGestureRecognizer(target: self, action: #selector(didTouch(gesture:)))
touchGesture.minimumPressDuration = 0.0
touchGesture.allowableMovement = CGFloat.greatestFiniteMagnitude
self.addGestureRecognizer(touchGesture)
}
required init?(coder aDecoder: NSCoder) {
fatalError("not implemented")
}
@objc
public func didTouch(gesture: UIGestureRecognizer) {
switch gesture.state {
case .possible:
break
case .began:
let location = gesture.location(in: self)
highlightActionView(location: location, fromView: self)
case .changed:
let location = gesture.location(in: self)
highlightActionView(location: location, fromView: self)
case .ended:
Logger.debug("\(logTag) in \(#function) ended")
let location = gesture.location(in: self)
selectActionView(location: location, fromView: self)
case .cancelled:
Logger.debug("\(logTag) in \(#function) canceled")
unhighlightAllActionViews()
case .failed:
Logger.debug("\(logTag) in \(#function) failed")
unhighlightAllActionViews()
}
}
public func addAction(_ action: MenuAction) {
actions.append(action)
let actionView = MenuActionView(action: action)
actionView.delegate = self
actions.append(action)
actionViews.append(actionView)
self.actionStackView.addArrangedSubview(actionView)
}
@ -329,6 +349,41 @@ class MenuActionSheetView: UIView, MenuActionViewDelegate {
mask.path = path.cgPath
self.layer.mask = mask
}
private func unhighlightAllActionViews() {
for actionView in actionViews {
actionView.isHighlighted = false
}
}
private func actionView(touchedBy touchPoint: CGPoint, fromView: UIView) -> MenuActionView? {
for actionView in actionViews {
let convertedPoint = actionView.convert(touchPoint, from: fromView)
if actionView.point(inside: convertedPoint, with: nil) {
return actionView
}
}
return nil
}
private func highlightActionView(location: CGPoint, fromView: UIView) {
guard let touchedView = actionView(touchedBy: location, fromView: fromView) else {
unhighlightAllActionViews()
return
}
touchedView.isHighlighted = true
self.actionViews.filter { $0 != touchedView }.forEach { $0.isHighlighted = false }
}
private func selectActionView(location: CGPoint, fromView: UIView) {
guard let selectedView: MenuActionView = actionView(touchedBy: location, fromView: fromView) else {
unhighlightAllActionViews()
return
}
selectedView.isHighlighted = true
self.actionViews.filter { $0 != selectedView }.forEach { $0.isHighlighted = false }
delegate?.actionSheet(self, didSelectAction: selectedView.action)
}
}
protocol MenuActionViewDelegate: class {
@ -337,7 +392,7 @@ protocol MenuActionViewDelegate: class {
class MenuActionView: UIButton {
public weak var delegate: MenuActionViewDelegate?
private let action: MenuAction
public let action: MenuAction
required init(action: MenuAction) {
self.action = action
@ -378,14 +433,15 @@ class MenuActionView: UIButton {
contentRow.isUserInteractionEnabled = false
self.addSubview(contentRow)
contentRow.ows_autoPinToSuperviewMargins()
contentRow.autoPinEdgesToSuperviewMargins()
contentRow.autoSetDimension(.height, toSize: 56, relation: .greaterThanOrEqual)
self.addTarget(self, action: #selector(didPress(sender:)), for: .touchUpInside)
self.isUserInteractionEnabled = false
}
override var isHighlighted: Bool {
didSet {
Logger.debug("\(logTag) in \(#function) \(oldValue) -> \(isHighlighted)")
self.backgroundColor = isHighlighted ? UIColor.ows_light10 : UIColor.white
}
}

Loading…
Cancel
Save