jc127
jc127

Reputation: 352

cancelTracking called unexpectedly when dragging in customized segmented control

I'm using the customized segmented control from this tutorial, in addition, I would like the selected segment to be changed on a swipe/drag, so I added these functions:

override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
    super.beginTracking(touch, with: event)
    
    let location = touch.location(in: self)
    lastTouchLocation = location

    return true
}

override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
    super.continueTracking(touch, with: event)
    
    let location = touch.location(in: self)
    print(location.x - lastTouchLocation!.x)
    
    let newX = thumbView.frame.origin.x + (location.x - lastTouchLocation!.x)
    if frame.minX <= newX && newX + thumbView.frame.width <= frame.maxX {
        thumbView.frame.origin.x = newX
    }
    lastTouchLocation = location
    
    return true
}

override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
    super.endTracking(touch, with: event)
    
    let location = touch != nil ? touch!.location(in: self) : lastTouchLocation!
    
    var calculatedIndex : Int?
    for (index, item) in labels.enumerated() {
        if item.frame.contains(location) {
            calculatedIndex = index
        }
    }
    
    if calculatedIndex != nil && calculatedIndex != selectedIndex {
        selectedIndex = calculatedIndex!
        sendActions(for: .valueChanged)
    } else {
        displayNewSelectedIndex()
    }
}

I've embedded the control in a UIView container, somehow the touch gets canceled when I drag the thumb view for a short distance

enter image description here

Could this be a problem with the view container, and how can I fix this?

Thank you if you've read the whole thing.

Upvotes: 1

Views: 411

Answers (1)

N.W
N.W

Reputation: 702

I ran into this recently when my custom UIControl was on a formsheet. It worked fine on a popover, but when I put the same control on a formsheet, it would abort the ability to drag sideways abruptly for seemingly no reason. cancelTracking was called but the event didn't tell me why. I figured out it had to do with iOS13's new way of dismissing Formsheets by dragging down. To fix it, I added this code to my class that extended UIControl:

override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    if gestureRecognizer is UIPanGestureRecognizer {
        return false
    }
    return true
}

Upvotes: 4

Related Questions