Hello,
I have created 5 UIViews, each with UIPanGestureRecognizers, which I then add to another UIView. All this works and I can drag each around, but I don’t want them to be dragged outside the boundaries of their parent UIView. I have read that I can implement UIGestureRecognizerDelegate with the gestureRecognizerShouldBegin function to achieve this, but I can’t find enough documentation on exactly how to achieve exactly what I need. Apple’s documentation on this, as usual, is quite vague. My code is:
let foreheadTopViewWidth = foreheadTopView.frame.width
let foreheadTopViewHeight = foreheadTopView.frame.height
let touchPointOffset = touchPointSize / 2
let touchPointYPos = (foreheadTopViewHeight / 2) - touchPointOffset
let touchPointForehead1 = TouchPoint(touchPointSize: touchPointSize, xPosition: 0, yPosition: touchPointYPos, treatmentArea: .upperForehead)
let touchPointForehead2 = TouchPoint(touchPointSize: touchPointSize, xPosition: ((foreheadTopViewWidth * 0.50) - touchPointOffset) / 2, yPosition: touchPointYPos, treatmentArea: .upperForehead)
let touchPointForehead3 = TouchPoint(touchPointSize: touchPointSize, xPosition: (foreheadTopViewWidth * 0.50) - touchPointOffset, yPosition: touchPointYPos, treatmentArea: .upperForehead)
let touchPointForehead4 = TouchPoint(touchPointSize: touchPointSize, xPosition: (foreheadTopViewWidth * 0.75) - (touchPointOffset / 0.75), yPosition: touchPointYPos, treatmentArea: .upperForehead)
let touchPointForehead5 = TouchPoint(touchPointSize: touchPointSize, xPosition: foreheadTopViewWidth - touchPointSize, yPosition: touchPointYPos, treatmentArea: .upperForehead)
foreheadTopView.addSubview(touchPointForehead1)
foreheadTopView.addSubview(touchPointForehead2)
foreheadTopView.addSubview(touchPointForehead3)
foreheadTopView.addSubview(touchPointForehead4)
foreheadTopView.addSubview(touchPointForehead5)
let foreheadGesture1 = UIPanGestureRecognizer(target: self, action: #selector(didPan(gesture:)))
let foreheadGesture2 = UIPanGestureRecognizer(target: self, action: #selector(didPan(gesture:)))
let foreheadGesture3 = UIPanGestureRecognizer(target: self, action: #selector(didPan(gesture:)))
let foreheadGesture4 = UIPanGestureRecognizer(target: self, action: #selector(didPan(gesture:)))
let foreheadGesture5 = UIPanGestureRecognizer(target: self, action: #selector(didPan(gesture:)))
foreheadGesture1.delegate = self
foreheadGesture2.delegate = self
foreheadGesture3.delegate = self
foreheadGesture4.delegate = self
foreheadGesture5.delegate = self
touchPointForehead1.addGestureRecognizer(foreheadGesture1)
touchPointForehead2.addGestureRecognizer(foreheadGesture2)
touchPointForehead3.addGestureRecognizer(foreheadGesture3)
touchPointForehead4.addGestureRecognizer(foreheadGesture4)
touchPointForehead5.addGestureRecognizer(foreheadGesture5)
foreheadTopView.layer.addSublayer(touchPointForehead1.lineTo(touchpoint: touchPointForehead2))
foreheadTopView.layer.addSublayer(touchPointForehead2.lineTo(touchpoint: touchPointForehead3))
foreheadTopView.layer.addSublayer(touchPointForehead3.lineTo(touchpoint: touchPointForehead4))
foreheadTopView.layer.addSublayer(touchPointForehead4.lineTo(touchpoint: touchPointForehead5))
@objc func didPan(gesture: UIPanGestureRecognizer) {
guard let touchpoint = gesture.view as? TouchPoint else {
return
}
if (gesture.state == .began) {
touchpoint.center = gesture.location(in: foreheadTopView)
}
let newCenter: CGPoint = gesture.location(in: foreheadTopView)
let dX = newCenter.x - touchpoint.center.x
let dY = newCenter.y - touchpoint.center.y
touchpoint.center = CGPoint(x: touchpoint.center.x + dX, y: touchpoint.center.y + dY)
if let outGoingTouchPoint = touchpoint.outGoingTouchPoint, let line = touchpoint.outGoingLine, let path = touchpoint.outGoingLine?.path {
let newPath = UIBezierPath(cgPath: path)
newPath.removeAllPoints()
newPath.move(to: touchpoint.center)
newPath.addLine(to: outGoingTouchPoint.center)
line.path = newPath.cgPath
}
if let inComingTouchPoint = touchpoint.inComingTouchPoint, let line = touchpoint.inComingLine, let path = touchpoint.inComingLine?.path {
let newPath = UIBezierPath(cgPath: path)
newPath.removeAllPoints()
newPath.move(to: inComingTouchPoint.center)
newPath.addLine(to: touchpoint.center)
line.path = newPath.cgPath
}
}
The above code works fine in terms of what I need it to do in terms of panning/dragging. I have also extended my ViewController to conform to UIGestureRecognizerDelegate
extension ViewController: UIGestureRecognizerDelegate {
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
}
}
But I am unsure where to go from here in how to restrict the draggable views within the boundaries of their parent view. Can anybody help?