Drag and drop UIButton but limit to boundaries

2019-04-16 18:11发布

问题:

I’m not asking for givemesamplecodenow responses, just a nudge in the right direction would be much appreciated. My searches haven’t been any good.

I have a UIButton that I am able to move freely around the screen.

I would like to limit the drag area on this object so it can only be moved up and down or side to side. I believe I need to get the x,y coordinates of the boundaries and then restrict movement outside this area. But that’s a far as I have got. My knowledge doesn’t stretch any further than that.

Has anyone implemented something similar in the past?

Adam

回答1:

So let's say you're in the middle of the drag operation. You're moving the button instance around by setting its center to the center of whatever gesture is causing the movement.

You can impose restrictions by testing the gesture's center and resetting the center values if you don't like them. The below assumes a button wired to an action for all Touch Drag events but the principle still applies if you're using gesture recognizers or touchesBegan: and friends.

- (IBAction)handleDrag:(UIButton *)sender forEvent:(UIEvent *)event 
{
    CGPoint point = [[[event allTouches] anyObject] locationInView:self.view];

    if (point.y > 200)
    {
        point.y = 200; //No dragging this button lower than 200px from the origin!
    }

    sender.center = point;
}

If you want a button that slides only on one axis, that's easy enough:

- (IBAction)handleDrag:(UIButton *)sender forEvent:(UIEvent *)event 
{
    CGPoint point = [[[event allTouches] anyObject] locationInView:self.view];  
    point.y = sender.center.y; //Always stick to the same y value

    sender.center = point;
}

Or perhaps you want the button draggable only inside the region of a specific view. This might be easier to define if your boundaries are complicated.

- (IBAction)handleDrag:(UIButton *)sender forEvent:(UIEvent *)event 
{   
    CGPoint point = [[[event allTouches] anyObject] locationInView:self.someView];

    if ([self.someView pointInside:point withEvent:nil])
    {
        sender.center = point; 
        //Only if the gesture center is inside the specified view will the button be moved
    }
}


回答2:

Presumably you'd be using touchesBegan:, touchesMoved:, etc., so it should be as simple as testing whether the touch point is outside your view's bounds in touchesMoved:. If it is outside, ignore it, but if it's inside, adjust the position of the button.

I suspect you may find this function useful:

bool CGRectContainsPoint ( CGRect rect, CGPoint point );