0

我有两个同心圆,它们之间的距离是一定的。我根据我在圆形部分(包括内部的黑色圆圈)触摸时获得的角度获得最外圈圆周上的坐标。

这是一个子类,UIControl我使用 touches 方法来获取圆周上的点。

我成功地得到了准确的角度,因此得到了最外圈圆周上的准确点。

但我想在同心圆顶部放置一个按钮,使其直径 = distance_between_concentric_circles + 2 * offset。

使用此偏移量是为了使按钮边缘应位于同心圆区域之外,如下图所示。

圆形按钮

每次我移动那个按钮时,它都应该沿着圆形路径移动。

由于我不想画画,我正在使用UIButton图像视图,我发现很难根据最外圈圆周上的点和UIButton.

我可以移动按钮,但它没有正确放置在圆形路径上。

谁能告诉我是否有办法让左上角坐标设置 uibutton 的框架?

我想在不画的情况下做到这一点。

4

2 回答 2

1

不用担心左上角可能更容易,而只需设置按钮的center属性(而不是frame属性)。计算左上角的偏移量并不难,但调整center属性要直观得多,恕我直言。


或者,如果您不想调整centerframe坐标,您可以使用 Quartz 2D 围绕屏幕上的某个点旋转按钮:

  • 更改按钮的anchorPoint

  • position按钮的 设置为您正在旋转的点(并且因为您已经设置了anchorPoint,所以按钮将从该点适当偏移position);和

  • 围绕该锚点旋转它。

因此,如果您将 QuartzCore.framework 链接到您的项目,您可以:

#import <QuartzCore/QuartzCore.h>

@interface ViewController ()

@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic) CFTimeInterval startTime;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self rotateButtonAroundPoint];
}

- (void)rotateButtonAroundPoint
{
    // the point about which I'm rotating and at what radius

    CGPoint center = CGPointMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0);
    CGFloat radius = 100.0;

    // now configure the button's layer accordingly

    self.button.layer.anchorPoint = CGPointMake(0.5, 0.5 + radius / self.button.frame.size.height);
    self.button.layer.position = center;

    // just so I can see what I'm rotating this around

    [self addCircleAt:center radius:5.0 color:[UIColor redColor]];

    // turn on display link to animate it (better than `NSTimer` for animations)

    [self startDisplayLink];
}

- (void)addCircleAt:(CGPoint)center radius:(CGFloat)radius color:(UIColor *)color
{
    CAShapeLayer *layer = [CAShapeLayer layer];
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:2.0 * M_PI clockwise:YES];

    layer.path = [path CGPath];
    layer.fillColor = [color CGColor];
    [self.view.layer addSublayer:layer];
}

- (void)startDisplayLink
{
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
    self.startTime = CACurrentMediaTime();
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

- (void)stopDisplayLink
{
    [self.displayLink invalidate];
    self.displayLink = nil;
}

- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
    CFTimeInterval elapsed = CACurrentMediaTime() - _startTime;

    self.button.transform = CGAffineTransformMakeRotation(elapsed * 2.0 * M_PI / 5.0); // duration = 5.0 seconds
}

我怀疑仅更改center/frame或进行平移(而不是这种旋转)在计算上可能会更便宜,但是如果您希望按钮在旋转时实际旋转,这是一种选择,并且它具有一定的优雅性(只是设置positionanchorPoint旋转它,根本不用担心笛卡尔坐标)。

于 2013-05-21T17:29:36.270 回答
0

以圆心为原点的圆的圆周上的任何一点都由原点表示(r*cos(theta),r*sin*(theta)) ,除原点外,圆周上的任何一点都(x+r*cos(theta),y+r*sin*(theta)) (x,y)将是圆的中心,因此计算(x+r*cos(theta),y+r*sin*(theta))并设置按钮中心

于 2013-05-21T13:12:58.397 回答