Чтобы сохранить представление изображения внутри его родителя, я добавил проверку перед обновлением центра представления, которая гарантирует, что кадр представлений будет находиться в кадре родителей.Центр обновляется только в том случае, если обновление сохранит представление в рамке его родителя.
Я также обновил обработчик панорамирования, чтобы использовать перевод (аналогично примеру в жесте панорамирования документация )в отличие от locationInView.Это делает перетаскивание себя лучше.
Я проверил это, и я считаю, что он ведет себя так, как вы хотите.Надеюсь, это поможет:
@objc func handlePan(nizer: UIPanGestureRecognizer!) {
if nizer.state == UIGestureRecognizer.State.began {
dragStartPositionRelativeToCenter = self.center
layer.shadowOffset = CGSize(width: 0, height: 20)
layer.shadowOpacity = 0.3
layer.shadowRadius = 6
return
}
if nizer.state == UIGestureRecognizer.State.ended {
dragStartPositionRelativeToCenter = nil
layer.shadowOffset = CGSize(width: 0, height: 3)
layer.shadowOpacity = 0.5
layer.shadowRadius = 2
return
}
if let initialCenter = dragStartPositionRelativeToCenter {
let translation = nizer.translation(in: self.superview)
let newCenter = CGPoint(x: initialCenter.x + translation.x, y: initialCenter.y + translation.y)
if frameContainsFrameFromCenter(containingFrame: superview!.frame, containedFrame: self.frame, center: newCenter) {
UIView.animate(withDuration: 0.1) {
self.center = newCenter
}
}
}
}
func frameContainsFrameFromCenter(containingFrame: CGRect, containedFrame: CGRect, center: CGPoint) -> Bool {
let leftMargin = containedFrame.width / 2
let topMargin = containedFrame.height / 2
let testFrame = CGRect(
x: leftMargin,
y: topMargin,
width: containingFrame.width - (2*leftMargin),
height: containingFrame.height - (2*topMargin)
)
return testFrame.contains(center)
}