开发者

Bounds checking for the center of a UIView while dragging it around

开发者 https://www.devze.com 2023-02-15 19:53 出处:网络
I have UIView elements that i want to drag around the screen. But i want that no-matter what, their center should be always inside the bounds of their superview.

I have UIView elements that i want to drag around the screen. But i want that no-matter what, their center should be always inside the bounds of their superview. I added to them an UIPanGestureRecognizer and i making the bounds checking as follows:

-(void) dragInProgress : (UIPanGestureRecognizer *) recognizer
{
    if ([self.delegate hallElement:self shouldMove:recognizer])
    {
        CGPoint translation = [recognizer translationInView:self.view.superview];

        CGPoint currentCenter = self.view.center;

        CGFloat maxX = self.view.superview.bounds.size.width;
        if (currentCenter.x + translation.x < 0 )
        {
            translation.x =  (0 - currentCenter.x);
        }
        if (currentCenter.x + translation.x >= maxX ) 
        {  
            translation.x = (maxX - currentCenter.x - 1);
        }

        CGFloat maxY = self.view.superview.bounds.size.height;
        if (currentCenter.y  + translation.y < 0 )    
        {  
            translation.y = (0 - currentCenter.y);
        }
        if (currentCenter.y + translation.y >= maxY ) 
        {  
            translation.y = (maxY - currentCenter.y - 1开发者_如何学C);
        }

        [recognizer setTranslation:translation inView:self.view.superview];
        CGPoint translationInViewCoordiateSystem = [recognizer translationInView:self.view];
        self.view.transform = CGAffineTransformTranslate(self.view.transform, translationInViewCoordiateSystem.x  ,  translationInViewCoordiateSystem.y  );
        [recognizer setTranslation:CGPointZero inView:self.view];
    }
}

But this bound checking is not working at the best case, and usually results in weird behavior. How can i ensure that the center will remain within the bounds of the superview?


Your centre isn't always going to be within the actual bounds -- it can go over by 1 pixel in the maximum X and Y directions. Not sure if that's causing your problem, but this code should fix that bounds issue:

CGPoint translation = [recognizer translationInView:self.view.superview];
CGPoint currentCenter = self.view.center;

CGFloat maxX = self.view.superview.bounds.size.width;
if (currentCenter.x + translation.x < 0 )
{
    translation.x =  (0 - currentCenter.x);
}

if (currentCenter.x + translation.x >= maxX ) // A CHANGE HERE
{  
    translation.x = (maxX - currentCenter.x - 1);  // A CHANGE HERE
}

CGFloat maxY = self.view.superview.bounds.size.height;
if (currentCenter.y  + translation.y < 0 )    
{  
    translation.y = (0 - currentCenter.y);
}

if (currentCenter.y + translation.y >= maxY ) // A CHANGE HERE
{  
    translation.y = (maxY - currentCenter.y - 1); // A CHANGE HERE
}


I figured out what was the problem: The transform translation is not changing the center of the view, so the bounds checking for the center is never really efficient because the center always stay the same even though the view is actually traveling across the screen.

So the solution will be to replace the following lines:

[recognizer setTranslation:translation inView:self.view.superview];
        CGPoint translationInViewCoordiateSystem = [recognizer translationInView:self.view];
        self.view.transform = CGAffineTransformTranslate(self.view.transform, translationInViewCoordiateSystem.x  ,  translationInViewCoordiateSystem.y  );
        [recognizer setTranslation:CGPointZero inView:self.view];

With:

currentCenter.x += translation.x;
currentCenter.y += translation.y;
self.view.center = currentCenter;
[recognizer setTranslation:CGPointZero inView:self.view.superview];
0

精彩评论

暂无评论...
验证码 换一张
取 消