Перемещение UIView в родительском UIView (UIPanGestureRecognizer)
Я использую следующий код для перемещения UIImageView, который присутствует внутри UIView.
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
Я хотел бы сделать так, чтобы UIView не перемещался за пределы родительского представления. В тот же момент изображение может перемещаться по всему экрану.
Ответы
Ответ 1
Сначала получите новый фрейм вашего UIImageView
и проверьте, полностью ли он внутри супервизора, используя метод CGRectContainsRect()
. Если да, установите рамку UImageView's
в новый кадр.
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:self.view];
CGRect recognizerFrame = recognizer.view.frame;
recognizerFrame.origin.x += translation.x;
recognizerFrame.origin.y += translation.y;
// Check if UIImageView is completely inside its superView
if (CGRectContainsRect(self.view.bounds, recognizerFrame)) {
recognizer.view.frame = recognizerFrame;
}
// Else check if UIImageView is vertically and/or horizontally outside of its
// superView. If yes, then set UImageView frame accordingly.
// This is required so that when user pans rapidly then it provides smooth translation.
else {
// Check vertically
if (recognizerFrame.origin.y < self.view.bounds.origin.y) {
recognizerFrame.origin.y = 0;
}
else if (recognizerFrame.origin.y + recognizerFrame.size.height > self.view.bounds.size.height) {
recognizerFrame.origin.y = self.view.bounds.size.height - recognizerFrame.size.height;
}
// Check horizantally
if (recognizerFrame.origin.x < self.view.bounds.origin.x) {
recognizerFrame.origin.x = 0;
}
else if (recognizerFrame.origin.x + recognizerFrame.size.width > self.view.bounds.size.width) {
recognizerFrame.origin.x = self.view.bounds.size.width - recognizerFrame.size.width;
}
}
// Reset translation so that on next pan recognition
// we get correct translation value
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
Убедитесь, что вы передали bounds
superView и frame
из UIImageView
, чтобы обе CGRects
находились в одной и той же системе координат.
Ответ 2
Попробуйте:
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer
{
if (gesture.state==UIGestureRecognizerStateChanged || gesture.state == UIGestureRecognizerStateEnded){
UIView *superview = recognizer.view.superview;
CGSize superviewSize = superview.bounds.size;
CGSize thisSize = recognizer.view.size;
CGPoint translation = [recognizer translationInView:self.view];
CGPoint center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
CGPoint resetTranslation = CGPointMake(translation.x, translation.y);
if(center.x - thisSize.width/2 < 0)
center.x = thisSize.width/2;
else if (center.x + thisSize.width/2 > superviewSize.width)
center.x = superviewSize.width-thisSize.width/2;
else
resetTranslation.x = 0; //Only reset the horizontal translation if the view *did* translate horizontally
if(center.y - thisSize.height/2 < 0)
center.y = thisSize.height/2;
else if(center.y + thisSize.height/2 > superviewSize.height)
center.y = superviewSize.height-thisSize.height/2;
else
resetTranslation.y = 0; //Only reset the vertical translation if the view *did* translate vertically
recognizer.view.center = center;
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
}
Таким образом, он никогда не будет перемещаться за пределы родительского представления, и он просто "прилипнет" к краю, если вы попытаетесь вывести его из пределов!
Ответ 3
Вам нужно установить значение recognizer.view.center
в новое значение, только если его frame
находится внутри bounds
его родительского представления. Используйте CGRectContainsRect
на recognizer.view.superview.bounds
и recognizer.view.frame
, чтобы убедиться, что они содержатся.
Если вы хотите, чтобы представление изображения перемещалось за пределы его родительского представления, пока центральная точка представления не находится за пределами родительских границ, вы можете использовать метод convertPoint:toView
UIView
и убедиться, что новый CGPoint
не находится за пределами ваших родительских границ.
Ответ 4
if (gesture.state==UIGestureRecognizerStateChanged){
CGPoint translation = [recognizer translationInView:self.view];
CGRect rectToCheck=CGRectMake(yourView.frame.origin.x+translation.x, yourView.frame.origin.y+translation.y, CGRectGetWidth(yourView.frame), CGRectGetHeight(yourView.frame));
if(CGRectContainsRect(self.view.bounds,rectToCheck))// check that the rect that is going to form lies within the bounds of self.view
{
yourView.frame=CGRectMake(yourView.frame.origin.x+translation.x, yourView.frame.origin.y+translation.y, CGRectGetWidth(yourView.frame), CGRectGetHeight(yourView.frame));
}
[gesture setTranslation:CGPointZero yourView]; // important to set this
}
P.S. Используйте блок состояния жестов для запуска, панорамирования, удаления. то есть UIGestureRecognizerStateBegan
UIGestureRecognizerStateChanged
UIGestureRecognizerStateEnded