首先,重置平移手势的平移(可能)更容易,因此我们正在计算相对移动:
if gestureRecognizer.state != .cancelled {
// translation will be + or - a small number of points
// do what's needed to move the view
// reset recognizer
gestureRecognizer.setTranslation(.zero, in: superV)
}
否则,假设您向右拖动(平移)300 点,但视图只能移动 20 点,那么直到您向左拖动 280 点,它才会开始向左移动。
所以,当水平拖动时,我们想在拖动视图位于其 superView 的左侧或右侧时停止...
- 计算 MAX centerX 位置
- 计算 MIN centerX 位置
- 这将是 superView 的宽度减去拖动视图宽度的 1/2
例如,如果superView的宽度是100,而drag-view的宽度是200,那么MAX centerX就是100,MIN centerX就是Zero。
然后我们对 centerY 位置做同样的事情。
尝试使用它作为你的 Pan Gesture 处理程序:
@objc func PangestureMethod(gestureRecognizer: UIPanGestureRecognizer){
// unwrap the view from the gesture
// AND
// unwrap that view's superView
guard let piece = gestureRecognizer.view,
let superV = piece.superview
else {
return
}
let translation = gestureRecognizer.translation(in: superV)
if gestureRecognizer.state == .began {
self.initialCenter = piece.center
}
if gestureRecognizer.state != .cancelled {
// what the new centerX and centerY will be
var newX: CGFloat = piece.center.x + translation.x
var newY: CGFloat = piece.center.y + translation.y
// MAX centerX is 1/2 the width of the piece's frame
let mxX = piece.frame.width * 0.5
// MIN centerX is Width of superView minus 1/2 the width of the piece's frame
let mnX = superV.bounds.width - piece.frame.width * 0.5
// make sure new centerX is neither greater than MAX nor less than MIN
newX = max(min(newX, mxX), mnX)
// MAX centerY is 1/2 the height of the piece's frame
let mxY = piece.frame.height * 0.5
// MIN centerY is Height of superView minus 1/2 the height of the piece's frame
let mnY = superV.bounds.height - piece.frame.height * 0.5
// make sure new centerY is neither greater than MAX nor less than MIN
newY = max(min(newY, mxY), mnY)
// set the new center
piece.center = CGPoint(x: newX, y: newY)
// reset recognizer
gestureRecognizer.setTranslation(.zero, in: superV)
}
else {
piece.center = initialCenter
}
}
编辑
为了防止 Pinch Gesture 将视图缩小到小于其 superView 帧,我们可以将手势中的新缩放值应用到视图 frame 的 CGRect,然后再将其应用到视图。
然后,仅当生成的矩形不小于 superView 的框架时才对视图应用缩放。
试试这个:
@objc func pinchRecognized(pinch: UIPinchGestureRecognizer) {
// unwrap the view from the gesture
// AND
// unwrap that view's superView
guard let piece = pinch.view,
let superV = piece.superview
else {
return
}
// this is a bit verbose for clarity
// get the new scale
let sc = pinch.scale
// get current frame of "piece" view
let currentPieceRect = piece.frame
// apply scaling transform to the rect
let futureRect = currentPieceRect.applying(CGAffineTransform(scaleX: sc, y: sc))
// if the resulting rect's width will be
// greater-than-or-equal to superView's width
if futureRect.width >= superV.bounds.width {
// go ahead and scale the piece view
piece.transform = piece.transform.scaledBy(x: sc, y: sc)
}
pinch.scale = 1
}