sushibrain
sushibrain

Reputation: 2780

Limit a UIPanGestureRecognizer to move inside of a specific view only

I'm trying to recreate the volume bar seen in iOS 11:

enter image description here

I tried doing that by creating a black (slightly) transparent UIView, and then adding a white subview to it. Through a UIPanGestureRecognizer I'm trying to actually give it the functionality I want to give it, though I want to limit that movement so:

Now the first thing was easy to figure out, however now I need to restrain it so it can't be moved higher or lower then the parent UIView

This is my code so far:

let gesture = UIPanGestureRecognizer(target: self, action: #selector(self.barWasDragged))
self.volumeBar.addGestureRecognizer(gesture)

 @objc func barWasDragged(gesture: UIPanGestureRecognizer) {
        switch gesture.state {
        case .began, .ended:
            viewCenter = self.volumeBar.center
        case .changed:
            let translation = gesture.translation(in: self)
            self.volumeBar.center.y = viewCenter!.y + translation.y
        default: break
        }
    }

But now, what is the best way to restrain it, can I perhaps just set bounds for the UIPanGestureRecognizer?

Thanks.

-- Edit

Just to clarify,

The black bar in the background is my volumeView, and de white (draggable) bar is my volumeBar

Upvotes: 1

Views: 517

Answers (1)

Malik
Malik

Reputation: 3802

As long as you know the frame for your volumeBar, you can do something like this

@objc func barWasDragged(gesture: UIPanGestureRecognizer) {
    switch gesture.state {
    case .began, .ended:
        viewCenter = self.volumeBar.center
    case .changed:
        let translation = gesture.translation(in: self)
        let newYValue = viewCenter.y + translation.y
        if newYValue > volumeBar.frame.origin.y && newYValue < (volumeBar.frame.origin.y+volumeBar.frame.size.height) {
            self.volumeBar.center.y = newYValue
        }
    default: break
    }
}

Upvotes: 1

Related Questions