触摸在UIButton内拖动5个像素而非默认1个像素

时间:2016-04-27 10:12:14

标签: ios swift events uibutton uicontrolevents

我在故事板上有一个UIButtonUIButton已与Touch Drag Inside操作myTouchDragInsideAction相关联。当用户从内部拖动按钮时会触发该操作(UIControlEventTouchDragInside)。

问题是在内部拖动1个像素后触发动作。然而,1个像素太敏感,只需轻轻一按手指即可触发。

@IBAction func myTouchDragInsideAction(sender: UIButton) {

    print("Button dragged inside")

}

问题:

如何在至少5个像素的移动后扩展此操作以仅触发内部拖动操作

2 个答案:

答案 0 :(得分:2)

您必须为其创建自定义按钮。以下CustomButton可能对您有帮助。

let DelayPoint:CGFloat = 5

class CustomButton: UIButton {

    var startPoint:CGPoint?

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

        if self.startPoint == nil {
          self.startPoint = touches.first?.previousLocationInView(self)
        }


        if self.shouldAllowForSendActionForPoint((touches.first?.locationInView(self))!) {
            super.touchesMoved(touches, withEvent: event)
        }
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.startPoint = nil
        super.touchesEnded(touches, withEvent: event)
    }

    func shouldAllowForSendActionForPoint(location:CGPoint) -> Bool {

        if self.startPoint != nil {

            let xDiff = (self.startPoint?.x)! - location.x
            let yDiff = (self.startPoint?.y)! - location.y

            if (xDiff > DelayPoint || xDiff < -DelayPoint || yDiff > DelayPoint || yDiff < -DelayPoint) {

                return true
            }
        }
        return false
    }
}

根据您的要求更改“DelayPoint”。 希望这会对你有所帮助。

答案 1 :(得分:0)

我为 Swift 3

实施solution
final class DraggedButton: UIButton {

    // MARK: - Public Properties
    @IBInspectable var sensitivityOfDrag: CGFloat = 5

    // MARK: - Private Properties
    private var startDragPoint: CGPoint?

    // MARK: - UIResponder
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let firstTouch = touches.first else {
            return
        }

        let location = firstTouch.location(in: self)
        let previousLocation = firstTouch.previousLocation(in: self)

        if startDragPoint == nil {
            startDragPoint = previousLocation
        }

        if shouldAllowForSendActionForPoint(location: location) {
            super.touchesMoved(touches, with: event)
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        startDragPoint = nil
        super.touchesEnded(touches, with: event)
    }

    // MARK: - Private methods
    private func shouldAllowForSendActionForPoint(location: CGPoint) -> Bool {
        guard let startDragPoint = startDragPoint else {
            return false
        }

        let xDifferent = abs(startDragPoint.x - location.x)
        let yDifferent = abs(startDragPoint.y - location.y)
        return xDifferent > sensitivityOfDrag || yDifferent > sensitivityOfDrag
    }
}