我有UIImageView
我通过名为DraggableImageView2
的自定义类创建了Draggable。然后,该类在带有图像的UIViewController
中实例化,并且可以在UIView
内拖动。问题是我想限制UIImageView
在拖动时不要经过特定的边界。这是我目前的代码:
import UIKit
class DraggableImageView2: UIImageView, UIGestureRecognizerDelegate {
var dragStartPositionRelativeToCenter : CGPoint?
var dragGesture: UIGestureRecognizer!
var zoomGesture: UIGestureRecognizer!
var lastKnownCenterX: CGFloat = 0.0
var lastKnownCenterY: CGFloat = 0.0
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initializeGestures()
}
override init(image: UIImage?) {
super.init(image: image)
self.initializeGestures()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.initializeGestures()
}
func initializeGestures() {
self.userInteractionEnabled = true
self.multipleTouchEnabled = true
dragGesture = UIPanGestureRecognizer(target: self, action: #selector(DraggableImageView.handlePan(_:)))
self.addGestureRecognizer(dragGesture)
}
func handlePan(recognizer: UIPanGestureRecognizer!) {
Scripts.log("PAN >>> MOVE ACTIVATED")
if recognizer.state == UIGestureRecognizerState.Began {
let locationInView = recognizer.locationInView(superview)
dragStartPositionRelativeToCenter = CGPoint(x: locationInView.x - center.x, y: locationInView.y - center.y)
return
}
if recognizer.state == UIGestureRecognizerState.Ended {
dragStartPositionRelativeToCenter = nil
return
}
let locationInView = recognizer.locationInView(superview)
Scripts.log("PAN LOCATION >>> X = \(self.frame.origin.x) | Y = \(self.frame.origin.y) | LX = \(locationInView.x) | LY = \(locationInView.y) | DX = \(self.dragStartPositionRelativeToCenter!.x) | DY = \(self.dragStartPositionRelativeToCenter!.y)")
let xDragMin: CGFloat = 1.0
let yDragMin: CGFloat = 1.0
let xDragMax: CGFloat = kDEVICE_WIDTH - self.frame.size.width - 1.0
let yDragMax: CGFloat = kDEVICE_WIDTH - self.frame.size.height - 1.0
var newCenterX: CGFloat = locationInView.x - self.dragStartPositionRelativeToCenter!.x
var newCenterY: CGFloat = locationInView.y - self.dragStartPositionRelativeToCenter!.y
if self.frame.origin.x < xDragMin {
Scripts.log("PAN LOCATION >>> X MIN PAST BOUNDS")
newCenterX = lastKnownCenterX
}
if self.frame.origin.y < yDragMin {
Scripts.log("PAN LOCATION >>> Y MIN PAST BOUNDS")
newCenterY = lastKnownCenterY
}
if self.frame.origin.x > xDragMax {
Scripts.log("PAN LOCATION >>> X MAX PAST BOUNDS")
}
if self.frame.origin.y > yDragMax {
Scripts.log("PAN LOCATION >>> Y MAX PAST BOUNDS")
}
UIView.animateWithDuration(0.1) {
self.center = CGPoint(x: newCenterX,
y: newCenterY)
}
lastKnownCenterX = newCenterX
lastKnownCenterY = newCenterY
}
func handlePinch(recognizer: UIPinchGestureRecognizer!) {
Scripts.log("PINCH >>> ZOOM ACTIVATED")
//self.bringSubviewToFront(recognizer.view!)
recognizer.view?.transform = CGAffineTransformScale((recognizer.view?.transform)!, recognizer.scale, recognizer.scale)
recognizer.scale = 1
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
Scripts.log("shouldRecognizeSimultaneouslyWithGestureRecognizer WAS CALLED")
return true
}
}
我才开始处理xDragMin
和yDragMin
部分。当它小于 xDragMin
时,一切都可以阻止它,但问题出现了一些奇怪的原因,当你试图拖出它时,它会在那个X点被冻结。对于 yDragMin
也是如此,如果达到最小值,它会停止,但不能拖出Y点。
答案 0 :(得分:0)
所以经过一些更多的挖掘和游戏,我似乎已经能够解决我自己的问题,至少对于X Bounds Min而言。这是我做的:
(1)添加了这些新变量
var isWithinXBounds: Bool = true
var lastKnownLX: CGFloat = 0.0
(2)以“if self.frame.origin.x&lt; xDragMin”开头的逻辑需要微调。这个条件非常好,直到它达到X界限。一旦它发生,那么self.frame.origin.x将永远不会改变(DUH)cos现在它的位置被锁定。我需要另一个条件来检查一旦界限被击中,即锁定,检查用户是否正在向+ ve方向移动。如果是,则将BOOL值设置回TRUE,这将解锁x位置
if self.frame.origin.x < xDragMin {
Scripts.log("PAN LOCATION >>> X MIN PAST BOUNDS")
self.isWithinXBounds = false
//If TOUCH still moving in negative direction
if locationInView.x - lastKnownLX < 0 {
newCenterX = lastKnownCenterX
}
else {
self.isWithinXBounds = true
}
}
(3)这是根据BOOL值解锁UIImageView的条件:
if isWithinXBounds {
lastKnownCenterX = newCenterX
lastKnownLX = locationInView.x
}