可拖动的UIButton Snap到圆形路径

时间:2013-08-14 03:56:39

标签: ios objective-c

您好我希望我的UIButton只能在我通过绘制矩形创建的圆圈中拖动。我可能需要制作一个圆形路径而不是圆形,但是我不太确定采用的方法,因为我是新手。这是我的代码,我只希望按钮被拖动到那个圆圈或不可见的路径。任何帮助或示例都会非常有帮助。谢谢!

编辑:我使用了下面的部分答案,但我不知道如何让它正常工作。我希望它与我创建的圆圈大小相同,所以我很乐意创建一个圆形路径并将其放在我制作的圆圈之上。

//Button Code
timeSetButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [timeSetButton addTarget:self
                         action:nil
               forControlEvents:UIControlEventTouchDown];
        [timeSetButton setImage:[UIImage imageNamed:@"testButton.png"] forState: UIControlStateNormal];
        timeSetButton.frame = CGRectMake(0,415,50,50);
        [self.view addSubview:timeSetButton];

        //Button Listener
        [timeSetButton addTarget:self action:@selector(wasDragged:withEvent:)
         forControlEvents:UIControlEventTouchDragInside];


//Draggable Button Code
// get the touch
UITouch *touch = [[event touchesForView:timeSetButton] anyObject];

// get delta
CGPoint previousLocation = [touch previousLocationInView:timeSetButton];
CGPoint location = [touch locationInView:timeSetButton];
CGFloat delta_x = location.x - previousLocation.x;
CGFloat delta_y = location.y - previousLocation.y;

// move button
timeSetButton.center = CGPointMake(timeSetButton.center.x + delta_x,
                            timeSetButton.center.y + delta_y);

// enforce constraint on locations, by...

// working out the distance from the centre of the circle
CGPoint vectorFromCentreOfCircle =
CGPointMake(150,150);

CGFloat distanceFromCentreOfCircle = hypotf(vectorFromCentreOfCircle.x, vectorFromCentreOfCircle.y);

// working out what you'd need to multiply that distance by in order
// to get the specified radius
CGFloat correctionMultiplier = 20 / distanceFromCentreOfCircle;

// adjust vector from centre of circle
vectorFromCentreOfCircle.x *= correctionMultiplier;
vectorFromCentreOfCircle.y *= correctionMultiplier;

// move button one more time
timeSetButton.center = CGPointMake(
                    200 + vectorFromCentreOfCircle.x,
                    200 + vectorFromCentreOfCircle.y);

这是圆形

circleView = [[CircleView alloc] initWithFrame:CGRectMake(55, 100, 260, 260)];
        circleView.backgroundColor = [UIColor clearColor];
        [self.view addSubview:circleView];
        [self.view sendSubviewToBack:circleView];

3 个答案:

答案 0 :(得分:2)

我实际上需要相同的并且正在观察您的代码。你真正需要做的是获取实际圆的角度,然后计算所需的x和y。我就是这样做的:

    UIButton *button = (UIButton *) sender;
UITouch *touch = [[event touchesForView:button] anyObject];

//Drawing the circle
CGPoint arcCenter = CGPointMake(385.0f, 700.0f);
CGFloat arcRadius = 140.0f;


// get delta
CGPoint previousLocation = [touch previousLocationInView:button];
CGPoint location = [touch locationInView:button];
CGFloat delta_x = location.x - previousLocation.x;
CGFloat delta_y = location.y - previousLocation.y;


// move button
button.center = CGPointMake(button.center.x + delta_x, button.center.y + delta_y);

CGFloat angle = atan2((button.center.y - arcCenter.y), (button.center.x - arcCenter.x));

button.center = CGPointMake(arcCenter.x + arcRadius * cos(angle), arcCenter.y + arcRadius * sin(angle));

当我向按钮添加拖动时,这给了我实际需要的行为。我使用Touch Drag Outside and Inside来避免当你的手指离按钮太远时按钮停止。我希望它也能帮到你。

答案 1 :(得分:1)

对于这类事情,在移动按钮以强制执行必须在圆上的约束之后,添加快速代码可能就足够了。 E.g。

// move button
timeSetButton.center = CGPointMake(button.center.x + delta_x,
                            button.center.y + delta_y);

// enforce constraint on locations, by...

// working out the distance from the centre of the circle
CGPoint vectorFromCentreOfCircle =
     CGPointMake(timeSetButton.center.x - centreOfCircle.x,
                 timeSetButton.center.x - centreOfCircle.y);

CGFloat distanceFromCentreOfCircle = 
     hypotf(vectorFromCentreOfCircle.x, vectorFromCentreOfCircle.y);

// working out what you'd need to multiply that distance by in order
// to get the specified radius
CGFloat correctionMultiplier = radiusOfCircle / distanceFromCentreOfCircle;

// adjust vector from centre of circle
vectorFromCentreOfCircle.x *= correctionMultiplier;
vectorFromCentreOfCircle.y *= correctionMultiplier;

// move button one more time
timeSetButton.center = CGPointMake(
          centreOfCircle.x + vectorFromCentreOfCircle.x,
          centreOfCircle.y + vectorFromCentreOfCircle.y);

答案 2 :(得分:0)

您只需知道touchPoint距视图中心的距离

即可

我将在您的代码中进行以下修改。看看是否有效

- (void)wasDragged:(UIButton *)button withEvent:(UIEvent *)event
{
    // get the touch
    UITouch *touch = [[event touchesForView:button] anyObject];

    // get delta
    CGPoint previousLocation = [touch previousLocationInView:button];
    CGPoint location = [touch locationInView:button];

    //calculate center of button in superView
    CGPoint buttonCenter = CGPointMake(button.frame.origin.x+(button.frame.size.width/2.0f),
                                       button.frame.origin.y+(button.frame.size.height/2.0f));
    //calculate the distance of current touchPoint from buttonCenter
    CGFloat diffx = location.x - buttonCenter.x;
    CGFloat diffy = location.y - buttonCenter.y;
    CGFloat distance = sqrtf((diffx*diffx)+(diffy*diffy));

    //check if the distance is within the radius of circle.
    //assuming that your button is always a square to make 
    //perfect circle within it.
    CGFloat radius = button.frame.size.width/2.0f;

    if(radius >= distance)//this makes a circular check.
    {
      CGFloat delta_x = location.x - previousLocation.x;
      CGFloat delta_y = location.y - previousLocation.y;

      // move button
      timeSetButton.center = CGPointMake(button.center.x + delta_x,
                                button.center.y + delta_y);
    }

}